2012-12-14 30 views
1

我有這樣的XML:XSLT重新排列XML節點(刪除其中的一些)和基於屬性值和名稱創建新節點

<?xml version="1.0" encoding="UTF-8"?> 
<General> 
    <Ports> 
     <Port> 
      <PortID>32434</PortID> 
      <PortName>PortName 1</PortName> 
      <Section> 
       <SectionHeader ID="63">General overview</SectionHeader> 
       <PAR ID="111">bla bla bla</PAR> 
      </Section> 
      <Section> 
       <SectionHeader ID="61">Max Size</SectionHeader> 
       <PAR ID="222">blu blu blu</PAR> 
      </Section> 
     </Port> 
     <Port> 
      <PortID>777</PortID> 
      <PortName>PortName 2</PortName> 
      <Section> 
       <SectionHeader ID="63">General overview</SectionHeader> 
       <PAR ID="333">bla2 bl2a bla2</PAR> 
      </Section> 
      <Section> 
       <SectionHeader ID="61">Max Size</SectionHeader> 
       <PAR ID="444">blu2 blu2 blu2</PAR> 
      </Section> 
     </Port> 
    </Ports> 
</General> 

,我需要有改造後該XML:

<?xml version="1.0" encoding="UTF-8"?> 
<Ports> 
    <Port> 
     <PortID>32434</PortID> 
     <PortName>PortName 1</PortName> 
     <PAR_111>bla bla bla</PAR_111> 
     <PAR_222>blu blu blu</PAR_222> 
    </Port> 
    <Port> 
     <PortID>777</PortID> 
     <PortName>PortName 2</PortName> 
     <PAR_333>bla2 bl2a bla2</PAR_333> 
     <PAR_444>blu2 blu2 blu2</PAR_444> 
    </Port> 
</Ports> 

基本上有幾個xsl需要覆蓋的東西: 1.重新排列節點並僅選擇PortID,PortName和PAR轉換爲xml(省略其他節點)。 2.採用PAR節點並創建名稱由名稱(PAR)和屬性值(ID)組合而成的節點。

我正在嘗試與每個和其他一些技術,但我失敗了。 這是我目前的版本,其中不工作

<?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:strip-space elements="*" /> 

    <xsl:for-each select="//Port"> 
     <xsl:copy-of select="*[name()='PortID' or name()='PortName']" /> 
     <xsl:copy-of select="Section/*[name()='PAR']"> 
      <xsl:element name="PAR_{@ID}"> 
       <xsl:value-of select="." /> 
      </xsl:element> 
     </xsl:copy-of> 
    </xsl:for-each> 

</xsl:stylesheet> 

非常感謝您的幫助!

+0

'copy-of'是一個* deep *副本,將它用於子元素(該內容永遠不會被評估)是沒有意義的。你幾乎總是想要'copy'而不是'copy-of'。 –

回答

3

您的xsl:for-each需要在xsl:template以內。然而,而是採用xsl:for-each,嘗試使用基於模板的方法(推而不是拉):

XML輸入

<General> 
    <Ports> 
     <Port> 
      <PortID>32434</PortID> 
      <PortName>PortName 1</PortName> 
      <Section> 
       <SectionHeader ID="63">General overview</SectionHeader> 
       <PAR ID="111">bla bla bla</PAR> 
      </Section> 
      <Section> 
       <SectionHeader ID="61">Max Size</SectionHeader> 
       <PAR ID="222">blu blu blu</PAR> 
      </Section> 
     </Port> 
     <Port> 
      <PortID>777</PortID> 
      <PortName>PortName 2</PortName> 
      <Section> 
       <SectionHeader ID="63">General overview</SectionHeader> 
       <PAR ID="333">bla2 bl2a bla2</PAR> 
      </Section> 
      <Section> 
       <SectionHeader ID="61">Max Size</SectionHeader> 
       <PAR ID="444">blu2 blu2 blu2</PAR> 
      </Section> 
     </Port> 
    </Ports> 
</General> 

XSLT 1.0

<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="General|Section"> 
     <xsl:apply-templates/> 
    </xsl:template> 

    <xsl:template match="SectionHeader"/> 

    <xsl:template match="PAR"> 
     <xsl:element name="PAR_{@ID}"> 
      <xsl:apply-templates/> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

XML輸出

<Ports> 
    <Port> 
     <PortID>32434</PortID> 
     <PortName>PortName 1</PortName> 
     <PAR_111>bla bla bla</PAR_111> 
     <PAR_222>blu blu blu</PAR_222> 
    </Port> 
    <Port> 
     <PortID>777</PortID> 
     <PortName>PortName 2</PortName> 
     <PAR_333>bla2 bl2a bla2</PAR_333> 
     <PAR_444>blu2 blu2 blu2</PAR_444> 
    </Port> 
</Ports> 
+0

太棒了。它的工作就像一個魅力:-)。非常感謝你。 – szymon