XSLT - 从XML创建重复节点

时间:2014-11-24 04:03:58

标签: xml xslt

我有一个多级XML,我需要使用XSLT 1.0复制一组带有新节点的节点。下面是一个示例xml。

<?xml version="1.0"?>
<Parent>
   <ChildL1 Childtype="A">
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1>
         <ChildL1L2/>
      </ChildL1L1>
   </ChildL1>
   <ChildL1 Childtype="B">
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1/>
   </ChildL1>
</Parent>

期望的输出:

<?xml version="1.0"?>
<Parent>
   <ChildL1 Childtype="A">
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1>
         <ChildL1L2/>
      </ChildL1L1>
   </ChildL1>
   <ChildL1 Childtype="B">
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1/>
   </ChildL1>
<NewNode>
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1/>
</NewNode>    
</Parent>

此处,NewNode仅在Childtype =“B”时具有ChildL1的Children节点。

先谢谢;如果这个问题不明确,请告诉我。这是我第一次发布这类问题。

编辑以显示更深层的xml节点:

<?xml version="1.0"?>
<Parent>
   <ChildL1 Childtype="A">
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1>
         <ChildL1L2>
            <ChildL1L3 index="1"/>
            <ChildL1L3 index="2"/>
            <ChildL1L3 index="3"/>
         </ChildL1L2>
      </ChildL1L1>
   </ChildL1>
   <ChildL1 Childtype="B">
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1/>
   </ChildL1>
</Parent>

所需的输出(选择Parent / ChildL1 / ChildL1L1 / ChildL1L2 / ChildL1L3,其中ChildL1 / Childtype ='A')

<?xml version="1.0"?>
<Parent>
   <ChildL1 Childtype="A">
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1>
         <ChildL1L2>
            <ChildL1L3 index="1"/>
            <ChildL1L3 index="2"/>
            <ChildL1L3 index="3"/>
         </ChildL1L2>
      </ChildL1L1>
   </ChildL1>
   <ChildL1 Childtype="B">
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1/>
   </ChildL1>
<NewNode>
            <ChildL1L3 index="1"/>
            <ChildL1L3 index="2"/>
            <ChildL1L3 index="3"/>
</NewNode>    
</Parent>

2 个答案:

答案 0 :(得分:1)

回答您编辑过的问题 - 这也很简单:

XSLT 1.0

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

<!-- identity transform -->
<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="@*|node()"/>
        <NewNode>
            <xsl:apply-templates select="ChildL1[@Childtype='A']/ChildL1L1/ChildL1L2/ChildL1L3"/>
        </NewNode>    
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

<强>结果

<?xml version="1.0" encoding="UTF-8"?>
<Parent>
   <ChildL1 Childtype="A">
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1>
         <ChildL1L2>
            <ChildL1L3 index="1"/>
            <ChildL1L3 index="2"/>
            <ChildL1L3 index="3"/>
         </ChildL1L2>
      </ChildL1L1>
   </ChildL1>
   <ChildL1 Childtype="B">
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1/>
   </ChildL1>
   <NewNode>
      <ChildL1L3 index="1"/>
      <ChildL1L3 index="2"/>
      <ChildL1L3 index="3"/>
   </NewNode>
</Parent>

答案 1 :(得分:0)

使用identity transform(以及复制子节点的变体)相当简单

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

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

    <xsl:template match="ChildL1[@Childtype='B']">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
        <NewNode>
            <xsl:copy-of select="child::node()"></xsl:copy-of>
        </NewNode>
    </xsl:template>

</xsl:stylesheet>

根据LeBarton's评论,您需要修复您的Xml,例如:

<?xml version="1.0"?>
<Parent>
   <ChildL1 Childtype="A">
      <ChildL1L1/>
      <ChildL1L1/>
      <ChildL1L1>
         <ChildL1L2 />
      </ChildL1L1>
   </ChildL1>
   <ChildL1 Childtype="B">
      <ChildL1L1/>
      <ChildL1L1 foo="bar"/>
      <ChildL1L1/>
   </ChildL1>
</Parent>

结果是(假设要复制ChildL1/@Childtype='B'个节点)

<?xml version="1.0" encoding="utf-8"?>
<Parent>
    <ChildL1 Childtype="A">
        <ChildL1L1 />
        <ChildL1L1 />
        <ChildL1L1>
            <ChildL1L2 />
        </ChildL1L1>
    </ChildL1>
    <ChildL1 Childtype="B">
        <ChildL1L1 />
        <ChildL1L1 foo="bar" />
        <ChildL1L1 />
    </ChildL1>
    <NewNode>
        <ChildL1L1 />
        <ChildL1L1 foo="bar" />
        <ChildL1L1 />
    </NewNode>
</Parent>