2014-11-24 82 views
1

我有一個多層次的XML,我需要使用XSLT 1.0複製一組具有新節點的節點。下面是一個示例xml。XSLT - 從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具有ChildL1的僅當Childtype = 「B」 子節點。

在此先感謝;讓我知道這個問題不清楚。這是我第一次發佈這類問題。

編輯顯示更深的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> 

期望的輸出(挑父/ 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

你的XML是無效的,而且它正在它正是你想要知道的困難。在第一個示例中,將打開,但不會關閉。此外,您有,但是從縮進中相應的關閉標記中,元素名稱不匹配。複製並粘貼到http://www.xmlvalidation.com/ – 2014-11-24 04:13:37

+0

對不起,並感謝您指出。我現在關閉了。我將嘗試@StuartLC解決方案 – mantlex 2014-11-24 04:28:08

+0

「*這裏的NewNode僅在Childtype =」B「時才具有ChildL1的Children節點。*」這不是我所看到的。恕我直言,如果你的節點有一個唯一的ID,你的問題會更清晰 - 所以你可以看到哪個ChildL1L1是哪個。 – 2014-11-24 05:41:57

回答

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

Hi @StuartLC的一部分,感謝您的迴應!我想我理解你的xslt的高層次方向。我將如何修改這個選擇比第一級更深的節點......比如第三級或第四級。 – mantlex 2014-11-24 04:34:19

+0

你能編輯你的問題來顯示你正在尋找的確切輸出嗎?例如而不是'child :: node()',你可以指定一個任意的xpath來複制到更深的後代。 – StuartLC 2014-11-24 05:07:27

+0

嗨@StuartLC,我現在更新了這個問題。我明白'child :: node()'是某種內置函數,所以想要看看如何選擇不是直接子節點的節點。 – mantlex 2014-11-24 05:51:30

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

謝謝!我將把它應用到我的數據場景中。再次感謝! – mantlex 2014-11-24 06:14:44