很难解释,所以我用XML讲。.
我要转换的XML文件
<Items>
<Item ID="1" Name="Student">
<Cell Name=""/>
<Cell Number=""/>
</Item>
<Item ID="1" Name="Professor">
<Cell Name=""/>
<Cell Number=""/>
</Item>
values.xml及其所有属性值
<students>
<count>2</count>
<student number="1">
<name>Peter</name>
<number>1234</number>
</student>
<student number="2">
<name>Stefan</name>
<number>4567</number>
</student>
</students>
所需的输出
<Items>
<Item ID="1" Name="Student">
<Cell Name="Max"/>
<Cell Number="1234"/>
</Student>
<Item ID="2" Name=Student>
<Cell Name="Stefan"/>
<Cell Number="4567"/>
</Professor>
</Items>
我的想法
<xsl:variable name="total" select="document('values.xml')"/>
<!-- Identity Transformation --> ||WORKS FINE||
<!-- copy students n-times --> ||WORKS FINE||
<!-- set attribute: name --> ||DOESN'T WORK||
<xsl:template match="v:Items/Item/Cell[1]">
<xsl:param name="c" select="1"/>
<xsl:param name="values" select="$total/students/student[@number=$c]"/>
<xsl:copy>
<xsl:attribute name="Name">
<xsl:copy-of select="$values/name"/>
</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
<xsl:if test="$c < $total/students/count">
<xsl:apply-templates select=".">
<xsl:with-param name="c" select="$c+1"/>
</xsl:apply-templates>
</xsl:if>
</xsl:template>
我在每个元素中都获得了两个属性值。 但是我想要第一个(Cell-)元素中的第一个属性值,第二个(Cell-)元素中的第二个属性值,依此类推。
答案 0 :(得分:1)
编辑:一种更简单的方法是计算XML中的位置,然后使用该位置来获取Cell
和student
的索引。
<xsl:template match="Items/Item">
<xsl:variable name="idx"><xsl:number /></xsl:variable> <!-- index of this 'Item' -->
<xsl:variable name="values" select="$total/student[@number=$idx]"/>
<xsl:copy>
<xsl:copy-of select="@*" /> <!-- copy attributes of this 'Item' -->
<xsl:apply-templates select="Cell">
<xsl:with-param name="cell" select="$values" /> <!-- pass current 'student' as parameter -->
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="Cell">
<xsl:param name="cell" />
<xsl:variable name="idx" select="position()" />
<xsl:variable name="firstAttr" select="name(@*[1])" /> <!-- get the name of the first attribute of this 'Cell' -->
<xsl:copy>
<xsl:attribute name="{$firstAttr}"> <!-- recreate attribute -->
<xsl:value-of select="$cell/*[$idx]"/> <!-- use position() of this 'Cell' as index in the current 'student' -->
</xsl:attribute>
</xsl:copy>
</xsl:template>
第二个模板将当前student
的 nth 个子元素放入 nth Cell
的第一个属性。
如果您只想匹配学生Cell
s,则可以使用一个空模板来过滤掉“教授” Item
s:
<xsl:template match="Items/Item[@Name='Professor']" />
然后用谓词从上方限制第一个模板:
<xsl:template match="Items/Item[@Name='Student']">
<xsl:variable name="idx" select="@ID"></xsl:variable>
...