我尝试在XSLT 2.0中进行转换
<data>
<attributes>
<attribute code="Name" datatyp="String" class="A"></attribute>
<attribute code="Age" datatyp="Integer" class="A"></attribute>
<attribute code="sex" datatyp="String" class="A"></attribute>
<attribute code="height" datatyp="Integer" class="B"></attribute>
</attributes>
<personal>
<name>Klaus</name>
<Age>16</Age>
<sex>male</sex>
<height>180</height>
</personal>
<personal>
<height>165</height>
</personal>
</data>
为Person 1
做类似的事情<personal>
<class>
<classtype>A</classtype>
<name>Klaus</name>
<Age>16</Age>
<sex>male</sex>
</class>
<class>
<classtype>B</classtype>
<height>180</height>
</class>
</personal>
<personal>
<class>
<classtype>B</classtype>
<height>165</height>
</class>
</personal>
哪个属性出现在哪个类的依赖项在Input XML的开头定义。我需要为每个人调用A类和B类的模板一次,这就是为什么我的尝试不能正常工作。
<xsl:for-each select="...personal/*">
<xsl:variable name="code"><xsl:value-of select="name()"></xsl:value-of> </xsl:variable>
<xsl:if test="//attribute[@code=$code]/@class='A'">
<!-- call template A -->
我需要一些帮助来解决根据给定参数调用正确模板的问题。
答案 0 :(得分:1)
这对你有用吗?
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="attr-by-code" match="attribute" use="@code" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="personal">
<xsl:copy>
<xsl:for-each-group select="*" group-by="key('attr-by-code', name())/@class">
<class>
<classtype>
<xsl:value-of select="current-grouping-key()" />
</classtype>
<xsl:apply-templates select="current-group()" />
</class>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
<xsl:template match="attributes"/>
</xsl:stylesheet>
答案 1 :(得分:0)
更简单,缩短两倍以上,保留顺序并且非常正确:
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="kAttrByCode" match="attribute" use="@code"/>
<xsl:template match="personal">
<xsl:copy>
<xsl:for-each-group select="*[key('kAttrByCode', name())]"
group-adjacent="key('kAttrByCode', name())/@class">
<class>
<classtype><xsl:sequence select="current-grouping-key()"/></classtype>
<xsl:sequence select="current-group()"/>
</class>
</xsl:for-each-group>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
对提供的XML文档应用此转换时(请注意code="Name"
已更正为code="name"
- 否则必须使用大小写转换函数来实现不区分大小写):
<data>
<attributes>
<attribute code="name" datatyp="String" class="A"></attribute>
<attribute code="Age" datatyp="Integer" class="A"></attribute>
<attribute code="sex" datatyp="String" class="A"></attribute>
<attribute code="height" datatyp="Integer" class="B"></attribute>
</attributes>
<personal>
<name>Klaus</name>
<Age>16</Age>
<sex>male</sex>
<height>180</height>
</personal>
<personal>
<height>165</height>
</personal>
</data>
产生了想要的正确结果:
<personal>
<class>
<classtype>A</classtype>
<name>Klaus</name>
<Age>16</Age>
<sex>male</sex>
</class>
<class>
<classtype>B</classtype>
<height>180</height>
</class>
</personal>
<personal>
<class>
<classtype>B</classtype>
<height>165</height>
</class>
</personal>
<强>解释强>:
将<xsl:for-each-group>
指令与属性group-adjacent
使用标准XSLT函数current-group()
和current-grouping-key()