0

源 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。

在源代码中,我们可以有多个父元素,每个父元素包含多个子元素。要生成目标,首先我们应该找到每个父项的所有子项的不同列表。因此,应该为源 xml 中的每个唯一 ItemNumber 映射目标 xml 中的父亲元素。你可以说它就像 sql 的 group-by 子句,我们在 ItemNumber 上为每个 Parent 分组。我希望这个例子能解释这种情况。

我一直在尝试各种事情,但还没有接近解决方案。我在形成解决方案时遇到了多个问题: 1. 我不认为我可以应用“Muenchian 方法”,因为我需要为每个 Parent 找到唯一的 ItemNumber。因此,必须在 for-each(parent) 元素内定义键。我在这里很困惑。2. 我认为,我应该为每个(父母)设置一个顶级水平。在其中,一种确定唯一 ItemNumber 的方法。然后,当我尝试使用来获取父名称时,我什么也得不到,因为当控件位于第二个 for-each(uniqueItemNumber) 内时,xpath (/name) 无效。很难解释这个问题。

我希望我能在这里得到解决方案。提前致谢。

4

1 回答 1

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>
于 2013-10-08T08:39:43.660 回答