将XML子节点移动到父级到XML的底部(在当前父节点之外)

时间:2014-05-23 18:03:39

标签: xslt

如何将XML文件中的某些子节点与Parent的一对多关系及其内容移动到父级外部的xml文件的底部。 首先是特定节点,然后可能是2个不同的节点。

在此示例中,我想将所有Child1及其内容移至<Parent>之外,并将其置于</Parent>之下且位于<Control> </Control>之内。

<Controls>
<Parent ID="1" Prop2="kk">
    ----
            <Child1 ID="1" Prop2="kk1">
                 ------
             </Child1>
             <Child2 ID="1" Prop2="kk2">
                 ------
             </Child2>
</Parent>
<Parent ID="2" Prop2="kk4">
    ----
            <Child1 ID="11" Prop2="kk5">
                 ------
             </Child1>
             <Child2 ID="11" Prop2="kk6">
                 ------
             </Child2>
</Parent>
<Parent ID="3" Prop2="kk7">
    ----
            <Child1 ID="111" Prop2="kk8">
                 ------
             </Child1>
             <Child2 ID="111" Prop2="kk9">
                 ------
             </Child2>
</Parent>
</Controls>

预期产出

<MyControls>
<Parent id="1">
    ----
             <Child2 id="1">
                 ------
             </Child2>
</Parent>
<Parent id="2">
    ----
             <Child2 id="11">
                 ------
             </Child2>
</Parent>
<Parent id="3">
    ----
             <Child2 id="111">
                 ------
             </Child2>
</Parent>

<Child1 id="1">
    ------
</Child1>

<Child1 id="11">
  ------
</Child1>
<Child1 id="111">
   ------
</Child1>
</MyControls>

使用过的XSLT

<xsl:template match="@*|node()">
<xsl:copy>
  <xsl:apply-templates select="@*|node()"/>
 </xsl:copy>
</xsl:template>      
 <xsl:template match="Child1">
 <Child1>     
    <xsl:apply-templates select="@*[not(self::Child1)]" />
    <xsl:apply-templates select="node()[not(self::Child1)]" />
 </Child1>    
</xsl:template>

1 个答案:

答案 0 :(得分:2)

您的样式表是一个开始,但您需要更多例外来阻止Child1内的Parent元素被复制。

尝试这样的事情:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Parent">
    <xsl:copy>
      <xsl:apply-templates select="@*"/>
      <xsl:apply-templates select="node()[not(self::Child1)]"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="Controls">
    <xsl:copy>
      <xsl:apply-templates select="Parent"/>
      <xsl:apply-templates select="Parent/Child1"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

请注意,Parent会获得特殊复制,其中除了Child1之外的所有后代都会被复制。在Controls s之前,ParentChild1明确排序。

在您的(略微修改以修复格式错误)源XML上运行时生成此输出:

<Controls>
  <Parent id="1">
    ----

             <Child2 id="1">
                 ------
             </Child2>
</Parent>
  <Parent id="2">
    ----

             <Child2 id="11">
                 ------
             </Child2>
</Parent>
  <Parent id="3">
    ----

             <Child2 id="111">
                 ------
             </Child2>
</Parent>
  <Child1 id="1">
                 ------
             </Child1>
  <Child1 id="11">
                 ------
             </Child1>
  <Child1 id="111">
                 ------
             </Child1>
</Controls>

基于评论中的请求的新XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Controls">
        <MyControls>
            <xsl:apply-templates select="@*|node()"/>
            <xsl:apply-templates select="Parent/Child1"/>
        </MyControls>
    </xsl:template>

    <xsl:template match="Parent">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()[not(self::Child1)]"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@ID">
        <xsl:attribute name="id">
            <xsl:value-of select="."/>
        </xsl:attribute>
    </xsl:template>

    <xsl:template match="@*[not(name()='ID')]"/>

</xsl:stylesheet>
相关问题