0

在这方面需要你的指导。

我正在尝试从非规范化的 XML 创建父子 XML:

从:

<Parent>Parent1</Parent>
<Child>Child1</Child>
<Parent>Parent2</Parent>
<Child>Child1</Child>
<Child>Child2</Child>
<Parent>Parent3</Parent>
<Child>Child1</Child>

到:

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

问题是我无法弄清楚要在每个父元素之间获取所有子元素的逻辑。

任何帮助表示赞赏。

非常感谢您对此进行调查。

4

1 回答 1

4

在 XSLT1.0 中,您可以使用密钥来实现这一点。您通过元素的第一个前面的元素有效地对子元素进行分组,因此您可以定义以下键:

<xsl:key name="child" match="Child" use="generate-id(preceding-sibling::Parent[1])"/>

然后,在匹配元素的模板中,您可以获得所有关联的元素,如下所示:

<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。在您的情况下,您希望从Parent元素开始对元素进行分组。

<xsl:for-each-group select="*" group-starting-with="Parent">

然后选择元素,你可以使用current-group函数:

<xsl:apply-templates select="current-group()[position() &gt; 1]" />

这是 2.0 的完整 XSLT

<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() &gt; 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>

这也应该输出相同的结果:

于 2013-02-14T21:16:38.733 回答