需要你的指导。
我正在尝试使用非规范化的XML创建父子XML:
FROM:
<Parent>Parent1</Parent>
<Child>Child1</Child>
<Parent>Parent2</Parent>
<Child>Child1</Child>
<Child>Child2</Child>
<Parent>Parent3</Parent>
<Child>Child1</Child>
TO:
<Parent>
<ParentValue>Parent1</ParentValue>
<Child>
<ChildValue>Child1</ChildValue>
</Child>
</Parent>
<Parent>
<ParentValue>Parent2</ParentValue>
<Child>
<ChildValue>Child1</ChildValue>
</Child>
<Child>
<ChildValue>Child2</ChildValue>
</Child>
</Parent>
<Parent>
<ParentValue>Parent3</ParentValue>
<Child>
<ChildValue>Child1</ChildValue>
</Child>
</Parent>
问题是我无法弄清楚要说的逻辑,在每个父元素之间获取所有Child元素。
感谢任何帮助。
非常感谢您对此进行调查。
答案 0 :(得分:4)
在XSLT1.0中,您可以使用密钥来实现此目的。您实际上是按照第一个 Parent 元素对 Child 元素进行分组,因此您可以定义以下键:
<xsl:key name="child" match="Child" use="generate-id(preceding-sibling::Parent[1])"/>
然后,在与 Parent 元素匹配的模板中,您可以获得所有关联的 Child 元素,如下所示:
<xsl:apply-templates select="key('child', 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="child" match="Child" use="generate-id(preceding-sibling::Parent[1])"/>
<xsl:template match="Family">
<Family>
<xsl:apply-templates select="Parent"/>
</Family>
</xsl:template>
<xsl:template match="Parent">
<Parent>
<ParentValue>
<xsl:value-of select="."/>
</ParentValue>
<xsl:apply-templates select="key('child', generate-id())"/>
</Parent>
</xsl:template>
<xsl:template match="Child">
<Child>
<ChildValue>
<xsl:value-of select="."/>
</ChildValue>
</Child>
</xsl:template>
</xsl:stylesheet>
当应用于XML时,输出以下内容:
<Family>
<Parent>
<ParentValue>Parent1</ParentValue>
<Child>
<ChildValue>Child1</ChildValue>
</Child>
</Parent>
<Parent>
<ParentValue>Parent2</ParentValue>
<Child>
<ChildValue>Child1</ChildValue>
</Child>
<Child>
<ChildValue>Child2</ChildValue>
</Child>
</Parent>
<Parent>
<ParentValue>Parent3</ParentValue>
<Child>
<ChildValue>Child1</ChildValue>
</Child>
</Parent>
</Family>
在XSLT2.0中,您可以使用 xsl:for-each-group 。在您的情况下,您希望将元素从父元素开始分组。
<xsl:for-each-group select="*" group-starting-with="Parent">
然后选择儿童元素,您可以使用当前组功能:
<xsl:apply-templates select="current-group()[position() > 1]" />
这是完整的XSLT for 2.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/Family">
<Family>
<xsl:for-each-group select="*" group-starting-with="Parent">
<Parent>
<ParentValue>
<xsl:value-of select="."/>
</ParentValue>
<xsl:apply-templates select="current-group()[position() > 1]" />
</Parent>
</xsl:for-each-group>
</Family>
</xsl:template>
<xsl:template match="Child">
<Child>
<ChildValue>
<xsl:value-of select="."/>
</ChildValue>
</Child>
</xsl:template>
</xsl:stylesheet>
这也应该输出相同的结果: