在 XSLT1.0 中执行此操作的一种方法是定义一个键,将person-list下的非 pid 元素按最前面的pid元素分组
<xsl:key
name="fields"
match="person-list/*[not(self::pid)]"
use="generate-id(preceding-sibling::pid[1])" />
然后,对于person-list元素,您将只选择pid元素
<xsl:apply-templates select="pid" />
在与pid匹配的模板中,您将创建一个person元素,并使用键输出其他元素:
<xsl:apply-templates select="key('fields', generate-id())" />
这是完整的 XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="fields" match="person-list/*[not(self::pid)]" use="generate-id(preceding-sibling::pid[1])" />
<xsl:template match="person-list">
<person-list>
<xsl:apply-templates select="pid" />
</person-list>
</xsl:template>
<xsl:template match="pid">
<person>
<xsl:copy-of select="." />
<xsl:apply-templates select="key('fields', generate-id())" />
</person>
</xsl:template>
<xsl:template match="@*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于您的示例 XML 时,将输出以下内容
<person-list>
<person>
<pid>100</pid>
<pname>Tom Jones</pname>
<pdescription>Some Text</pdescription>
</person>
<person>
<pid>101</pid>
<pname>John Thomas</pname>
<pdescription></pdescription>
</person>
</person-list>
请注意,通过这种方法,您可以向每个人的输入文档添加更多字段,而无需修改 XSLT。
还要注意使用“身份转换”来复制现有元素。