源XML:
<r:root xmlns:r="http://root/">
<p:parent xmlns:p="http://parent/">
<p:name>John</name>
<p:age>30</age>
<c:child xmlns:c="http://child/">
<c:cname>John_child_1</cname>
<c:cage/>
<c:ItemNumber>1</ItemNumber>
</child>
<c:child xmlns:c="http://child/">
<c:cname>John_child_2</cname>
<c:cage/>
<c:ItemNumber>2</ItemNumber>
</child>
<c:child xmlns:c="http://child/">
<c:cname>John_child_3</cname>
<c:cage/>
<c:ItemNumber>1</ItemNumber>
</child>
</parent>
<p:parent>
<p:name>Doe</name>
<p:age>40</age>
<c:child xmlns:c="http://child/">
<c:cname>Doe_child_1</cname>
<c:cage/>
<c:ItemNumber>2</ItemNumber>
</child>
<c:child xmlns:c="http://child/">
<c:cname>Doe_child_2</cname>
<c:cage/>
<c:ItemNumber>2</ItemNumber>
</child>
</parent>
...
...
...
目标XML:
<root>
<f:father xmlns:f="http://father/">
<f:name>John</name>
<f:age>30</age>
<f:UniqueItemNumber>1</UniqueItemNumber>
<c:child xmlns:c="http://child/">
<c:cname>John_child_1</cname>
<c:cage/>
<c:ItemNumber>1</ItemNumber>
</child>
<c:child xmlns:c="http://child/">
<c:cname>John_child_3</cname>
<c:cage/>
<c:ItemNumber>1</ItemNumber>
</child>
</father>
<f:father xmlns:f="http://father/">
<f:name>John</name>
<f:age>30</age>
<f:UniqueItemNumber>2</UniqueItemNumber>
<c:child xmlns:c="http://child/">
<c:cname>John_child_2</cname>
<c:cage/>
<c:ItemNumber>2</ItemNumber>
</child>
</father>
<f:father xmlns:f="http://father/">
<f:name>Doe</name>
<f:age>40</age>
<f:UniqueItemNumber>2</UniqueItemNumber>
<c:child xmlns:c="http://child/">
<c:cname>Doe_child_1</cname>
<c:cage/>
<c:ItemNumber>2</ItemNumber>
</child>
<c:child xmlns:c="http://child/">
<c:cname>Doe_child_2</cname>
<c:cage/>
<c:ItemNumber>2</ItemNumber>
</child>
</father>
....
...
我有一个源xml,我想使用XSLT将其转换为显示的目标xml。
在源代码中,我们可以拥有多个父元素,每个元素包含多个子元素。要生成目标,首先我们应该为每个父项找到所有子项的ItemNumber的不同列表。因此,应该为源xml中的每个唯一ItemNumber映射目标xml中的父元素。你可以说它就像是sql的group-by子句,我们在每个Parent的ItemNumber上进行分组。我希望这个例子可以解释这种情况。
我一直在尝试各种各样的事情,但还没有达到解决方案的附近。我在形成解决方案时遇到了多个问题: 1.我认为我不能应用“Muenchian Method”,因为我需要为每个Parent找到唯一的ItemNumber。因此,必须在for-each(父)元素内定义键。我在这里很困惑。 我想,我应该为每个人(父母)提供一个顶级水平。在其中,一种确定唯一ItemNumber的方法。然后,当我尝试使用获取Parent Name时,我得不到任何东西,因为当控件在第二个for-each(uniqueItemNumber)内时,xpath(/ name)isn; t无效。解释这个问题很难。
我希望我能在这里找到解决方案。提前谢谢。
答案 0 :(得分:0)
你可以使用Muenchian分组在这样的元素中分组,诀窍是在每个父元素中包含一些独特的东西作为分组键的一部分。其generate-id()
通常是一个很好的候选人。
<xsl:key name="childrenByNumber "match="c:child"
use="concat(generate-id(..), '+', c:ItemNumber)"/>
如果要在父项中提取组,则以相同的方式构造查找键:
<xsl:template match="p:parent">
<xsl:variable name="p" select="."/>
<xsl:for-each select="c:child[generate-id() =
generate-id(key('childrenByNumber', concat(generate-id($p), '+', c:ItemNumber))[1])]">
<f:father xmlns:f="http://father/">
<f:name><xsl:value-of select="$p/p:name"/></f:name>
<f:age><xsl:value-of select="$p/p:age"/></f:age>
<f:uniqueItemNumber>
<xsl:value-of select="c:ItemNumber"/>
</f:uniqueItemNumber>
<xsl:copy-of select="key('childrenByNumber', concat(generate-id($p), '+', c:ItemNumber))"/>
</f:father>
</xsl:for-each>
</xsl:template>