2013-03-02 58 views
2

我以下的问题看的代码示例:要创建什么?一个函数或模板还是?

<xsl:if test="/Document/test/id"> 
    <TEST1> 
    <xsl:value-of select="/Document/test/id"/> 
    </TEST1> 
</xsl:if> 

我有一个巨大的XSLT脚本用了很多相同的代码。我想创建一个函数,但我得到了所有的时间错误。我问自己,如果这是解决这个问题的正确解决方案。

为了使代码更好地维护,我想使用类似下面的内容。 这不是xslt的语法,因为我不知道如何,但给一个想法,我在找什么。

... 
<xsl:something "TEST1", "/Document/test/id1" /> 
<xsl:something "TEST2", "/Document/test/id2" /> 
... 

的代码将是更好的可读性和可维护性,虽然我不知道如何解决这个:-( 任何建议,欢迎...

问候德克

回答

2

这种转变

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:my="my:my" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:variable name="vDoc" select="/"/> 

<xsl:template match="/"> 
    <xsl:sequence select="my:test(xs:QName('Test1'), /*/test/id1/string())"/> 
    <xsl:sequence select="my:test(xs:QName('Test2'), /*/test/id2/string())"/> 
    <xsl:sequence select="my:test(xs:QName('Test3'), /*/test/id3/string())"/> 
    <xsl:sequence select="my:test(xs:QName('Test4'), /*/test/id4/string())"/> 
</xsl:template> 

<xsl:function name="my:test"> 
    <xsl:param name="pName" as="xs:QName"/> 
    <xsl:param name="pToPresent" as="item()?"/> 

    <xsl:if test="$pToPresent"> 
    <xsl:element name="{$pName}"> 
      <xsl:sequence select="$pToPresent"/> 
    </xsl:element> 
    </xsl:if> 
</xsl:function> 
</xsl:stylesheet> 

当在下面的XML文档应用:

<Document> 
<test> 
    <id1>Some Id1</id1> 
</test> 
<test> 
    <id2>Some Id2</id2> 
</test> 
<test> 
    <id4>Some Id4</id4> 
</test> 
</Document> 

想要的,正确的结果产生:

<Test1>Some Id1</Test1> 
<Test2>Some Id2</Test2> 
<Test4>Some Id4</Test4> 

请注意

  1. my:test()第一个参数声明xs:QName类型,这保证了那个价值的name attri xsl:element指令的bute始终是有效的名称。

  2. my:test()第二个参数被声明非常松散item()?型的,这给了我们自由提供任何类型的项目(字符串或节点或元素,或者......),并恰好提供了什么会被复制“原样”。

+0

嗨,非常感谢你的回答。我看到我自己的例子中出了什么问题。在我自己的例子中,我没有从xpath表达式获取内容,但只有字符串是这样的。我得到的原始XML有命名空间。这可能是问题吗? – Dirk 2013-03-03 11:06:07

+0

你好Dimitre谢谢,它按预期工作。现在发生的唯一情况是我输入的内容如下: Somde Id1我该如何摆脱空的xmlns? – Dirk 2013-03-03 13:23:14

+0

@Dirk,请提出一个新问题并提供您正在使用的确切XML文档,以便读者和潜在的回复者不必猜测。 – 2013-03-03 15:31:12

2

我觉得这是最接近你要什么:如果这是在接下来的输入运行

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:f="custom-functions" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="/"> 
    <CONTENT> 
     <xsl:sequence select="f:rename('TEST1', /Document/test/id1)"/> 
     <xsl:sequence select="f:rename('TEST2', /Document/test/id2)"/> 
    </CONTENT> 
    </xsl:template> 

    <xsl:function name="f:rename"> 
    <xsl:param name="name" as="xs:string"/> 
    <xsl:param name="toWrap" /> 

    <xsl:if test="$toWrap"> 
     <xsl:element name="{$name}"> 
     <xsl:value-of select="$toWrap"/> 
     </xsl:element> 
    </xsl:if> 
    </xsl:function> 
</xsl:stylesheet> 

<Document> 
    <test> 
    <id1>Hello!</id1> 
    <id2>Hello again!</id2> 
    </test> 
</Document> 

产生的输出是:

<CONTENT> 
    <TEST1>Hello!</TEST1> 
    <TEST2>Hello again!</TEST2> 
</CONTENT> 

你也可以试试这个,我i稍微详细些,但XSLT 1.0兼容:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output omit-xml-declaration="yes" indent="yes"/> 

    <xsl:template match="/"> 
    <CONTENT> 
     <xsl:apply-templates select="/Document/test/id1" mode="rename"> 
     <xsl:with-param name="name" select="'TEST1'" /> 
     </xsl:apply-templates> 
     <xsl:apply-templates select="/Document/test/id2" mode="rename"> 
     <xsl:with-param name="name" select="'TEST2'" /> 
     </xsl:apply-templates> 
    </CONTENT> 
    </xsl:template> 

    <xsl:template match="@* | node()" mode="rename"> 
    <xsl:param name="name" /> 
    <xsl:element name="{$name}"> 
     <xsl:value-of select="." /> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

当在上面的示例XML上运行时,会再次生成相同的输出。

+0

非常感谢你,这也是我一直在寻找的地方。正如我在上面的答案中所述。我原来的消息有名称空间。当我在解决方案中使用xlst2解决方案时,将打印xpath表达式而不是表达式的内容。任何想法我需要做什么来获取内容? – Dirk 2013-03-03 11:09:11

+0

我看不出为什么它会打印出XPath表达式,除非你对它做了一些奇怪的事情。你能提供一个上面的例子来说明你的实际输入XML,包括命名空间吗? – JLRishe 2013-03-03 13:22:57

相关问题