我遇到以下问题,请参阅代码示例:
<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" />
...
代码会更好的可读性和可维护性,虽然我不知道如何解决这个问题:-( 欢迎任何建议......
关心Dirk
答案 0 :(得分: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>
请注意:
my:test()
的第一个参数声明为xs:QName
类型,它保证name
指令的xsl:element
属性的值始终有效名称
my:test()
的第二个参数被非常松散地声明为item()?
类型,这使我们可以自由地提供任何类型的项目(字符串或节点或元素,或......)并且确切地提供的内容将“按原样”再现。
答案 1 :(得分: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>
您也可以尝试这个,这有点冗长,但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上运行时,会再次生成相同的输出。