2015-08-30 24 views
1

我有一個xml,其中有一個簡單形式的partyId和parentPartyId值。我想將它轉換成分層樹格式的形式。將XML轉換爲分層格式的XSLT

我已根據所需的輸出創建了架構。我正在嘗試使用http://www.keller.com/xslt/8/中的Axis名稱表達式。我沒有得到,如何將源代碼轉換爲所需的格式?

來源和要求的目標如下。

來源:

<OutputCollection xmlns="http://xmlns.test.com/pcbpel/adapter/db/PartyHierarchy"> 
      <Output> 
       <level>1</level> 
       <Parent_Party xsi:nil="true"/> 
       <Party>Party-1</Party> 
      </Output> 
      <Output> 
       <level>2</level> 
       <Parent_Party>Party-1</Parent_Party> 
       <Party>Party-1-1</Party> 
      </Output> 
      <Output> 
       <level>2</level> 
       <Parent_Party>Party-1</Parent_Party> 
       <Party>Party-1-2</Party> 
      </Output> 
      <Output> 
       <level>3</level> 
       <Parent_Party>Party-1-2</Parent_Party> 
       <Party>Party-1-2-1</Party> 
      </Output> 
      <Output> 
       <level>3</level> 
       <Parent_Party>Party-1-2</Parent_Party> 
       <Party>Party-1-2-2</Party> 
      </Output> 
      <Output> 
       <level>3</level> 
       <Parent_Party>Party-1-2</Parent_Party> 
       <Party>Party-1-2-3</Party> 
      </Output> 
      <Output> 
       <level>2</level> 
       <Parent_Party>Party-1</Parent_Party> 
       <Party>Party-1-3</Party> 
      </Output> 
      <Output> 
       <level>3</level> 
       <Parent_Party>Party-1-3</Parent_Party> 
       <Party>Party-1-3-1</Party> 
      </Output> 
      <Output> 
       <level>3</level> 
       <Parent_Party>Party-1-3</Parent_Party> 
       <Party>Party-1-3-2</Party> 
      </Output> 
     </OutputCollection> 

目標:

<OutputCollection xmlns="http://xmlns.test.com/pcbpel/adapter/db/PartyHierarchy"> 
      <Output> 
       <level>1</level> 
       <Parent_Party xsi:nil="true"/> 
       <Party>Party-1</Party> 
       <Children> 
        <level>2</level> 
        <Parent_Party>Party-1</Parent_Party> 
        <Party>Party-1-1</Party> 
       </Children> 
       <Children> 
        <level>2</level> 
        <Parent_Party>Party-1</Parent_Party> 
        <Party>Party-1-2</Party> 
        <Children> 
         <level>3</level> 
         <Parent_Party>Party-1-2</Parent_Party> 
         <Party>Party-1-2-1</Party> 
        </Children> 
        <Children> 
         <level>3</level> 
         <Parent_Party>Party-1-2</Parent_Party> 
         <Party>Party-1-2-2</Party> 
        </Children> 
        <Children> 
         <level>3</level> 
         <Parent_Party>Party-1-2</Parent_Party> 
         <Party>Party-1-2-3</Party>     
        </Children> 
       </Children> 
       <Children> 
        <level>2</level> 
        <Parent_Party>Party-1</Parent_Party> 
        <Party>Party-1-3</Party> 
        <Children> 
         <level>3</level> 
         <Parent_Party>Party-1-3</Parent_Party> 
         <Party>Party-1-3-1</Party>     
        </Children> 
        <Children> 
         <level>3</level> 
         <Parent_Party>Party-1-3</Parent_Party> 
         <Party>Party-1-3-2</Party>   
        </Children>     
       </Children> 
      </Output> 
     </OutputCollection> 

回答

2

使用XSLT,如果你需要遵循交叉引用,那麼你需要定義一個關鍵<xsl:key name="children" match="ph:Output" use="ph:Parent_Party"/>並使用它<xsl:apply-templates select="key('children', ph:Party)"/>

<xsl:stylesheet 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ph="http://xmlns.test.com/pcbpel/adapter/db/PartyHierarchy" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns="http://xmlns.test.com/pcbpel/adapter/db/PartyHierarchy" 
    exclude-result-prefixes="ph xsi" 
    version="1.0"> 

<xsl:output indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:key name="children" match="ph:Output" use="ph:Parent_Party"/> 

<xsl:template match="/*"> 
    <xsl:copy> 
    <xsl:apply-templates select="key('children', '')"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="ph:Output[ph:Parent_Party/@xsi:nil = 'true']"> 
    <xsl:copy> 
    <xsl:copy-of select="node()"/> 
    <xsl:apply-templates select="key('children', ph:Party)"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="ph:Output"> 
    <children> 
    <xsl:copy-of select="node()"/> 
    <xsl:apply-templates select="key('children', ph:Party)"/> 
    </children> 
</xsl:template> 

</xsl:stylesheet> 

請注意,您發佈的輸入示例使用前綴xsi,但未聲明它,因此我不得不假定該前綴的名稱空間。

+0

非常感謝,馬丁!我花了大量的時間在以下,之前等,但這種解決方案的工作原理非常簡潔。 我是高級XSLT新手。你能否建議任何關於概念或類似問題的鏈接來練習? –

+0

有一個常見問題彙編http://www.dpawson.co.uk/xsl/sect2/sect21.html。而且,您應該能夠在各種出版商提供的專用於XSLT和XPath的書中找到對概念的深入說明。網上也有資源http://www.cranesoftwrights.com/training/index.htm,http://stackoverflow.com/tags/xslt/info頁面也有鏈接到在線課程。 –

+0

謝謝馬丁! 如果可能的話,你能否展示一下,我們如何使用Axis名稱(即.sibling ::,之前::等)來實現相同的輸出。 –