使用此输入XML:
<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Employee ID="1">
<FirstName>Klaus</FirstName>
<LastName>Salchner</LastName>
</Employee>
<Employee ID="2">
<FirstName>Peter</FirstName>
<LastName>Pan</LastName>
</Employee>
</Employees>
你如何得到这个输出:
<Employees>
<FirstName>
<Employee>Klaus</Employee>
<Employee>Peter</Employee>
</FirstName>
<LastName>
<Employee>Salchner</Employee>
<Employee>Pan</Employee>
</LastName>
</Employees>
但是,如果您不知道Employee元素中将有多少字段 - 但是,我们假设相同的元素(这里是FirstName和LastnName)肯定会出现在每个Employee元素中。< / p>
我得到的最好的是:
<Employees>
<xsl:for-each select="*/Employee/.">
<xsl:value-of select=".">
<xsl:value-of select="./." />
</xsl:value-of>
</xsl:for-each>
</Employees>
我知道这是错的!
答案 0 :(得分:1)
此转化:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kElsByName" match="Employee/*"
use="name()"/>
<xsl:template match="/*">
<Employees>
<xsl:for-each select=
"Employee/*[generate-id()
=
generate-id(key('kElsByName', name())[1])
]">
<xsl:element name="{name()}">
<xsl:for-each select="key('kElsByName', name())">
<Employee>
<xsl:value-of select="."/>
</Employee>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</Employees>
</xsl:template>
</xsl:stylesheet>
应用于此XML文档时(添加<DOB>
以使其通用):
<Employees>
<Employee ID="1">
<FirstName>Klaus</FirstName>
<LastName>Salchner</LastName>
<DOB>19670823</DOB>
</Employee>
<Employee ID="2">
<FirstName>Peter</FirstName>
<LastName>Pan</LastName>
<DOB>19881113</DOB>
</Employee>
</Employees>
产生想要的结果:
<Employees>
<FirstName>
<Employee>Klaus</Employee>
<Employee>Peter</Employee>
</FirstName>
<LastName>
<Employee>Salchner</Employee>
<Employee>Pan</Employee>
</LastName>
<DOB>
<Employee>19670823</Employee>
<Employee>19881113</Employee>
</DOB>
</Employees>
请注意:
使用密钥和使用Muenchian方法进行分组,以查找Employee
的子元素的所有不同名称。
<xsl:element>
使用AVT为其name
属性生成编译时名称未知的元素。
答案 1 :(得分:0)
如果您需要多次处理节点,可以使用template modes。以下是:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="Employees">
<Employees>
<FirstName>
<xsl:apply-templates mode="firstname" />
</FirstName>
<LastName>
<xsl:apply-templates mode="lastname" />
</LastName>
</Employees>
</xsl:template>
<xsl:template match="Employee" mode="firstname">
<Employee>
<xsl:value-of select="FirstName"/>
</Employee>
</xsl:template>
<xsl:template match="Employee" mode="lastname">
<Employee>
<xsl:value-of select="LastName"/>
</Employee>
</xsl:template>
</xsl:stylesheet>
答案 2 :(得分:0)
好吧,我最终解决了这个问题 - 基本上我需要第一个Employee中元素的for-each,并将for-each中的变量赋值给position()值。
然后,在第二个嵌套的for-each中,我遍历外部Employee元素。
对于每个Employee元素,我使用变量(包含内部元素的“row”)来索引它的内部元素。
类似的东西:
<xsl:for-each select="*/Employee[1]/.">
<tr>
<xsl:variable name="row" select="position()" />
<xsl:for-each select="/*/Employee">
<td>
<xsl:value-of select=".[$row]/."/>
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
我承认,我的内容更简洁一点,但这就是要点。
简而言之(深呼吸)循环遍历第一个外部元素的元素列表。对于每一个,循环遍历外部元素并使用内部元素的索引顺序选择内部元素。