2016-01-28 29 views
1

我有一個複雜的XML輸入,我需要將其轉換爲平面結構,通過重複相關節點來對XML文檔中的樹進行解構。在XSL中使用以下參數時限制結果

源XML lookes這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="forom%20sample.xsl"?> 
<Customers> 
    <Customer> 
     <ID>1</ID> 
     <Name>John Madsen</Name> 
     <Accounts> 
      <Account> 
       <ID>111</ID> 
       <Name>AAA</Name> 
       <Value>11234</Value>     
      </Account> 
      <Account> 
       <ID>222</ID> 
       <Name>BBB</Name> 
       <Value>64</Value> 
      </Account> 
     </Accounts> 
     <Profile> 
      <Gender>M</Gender> 
      <Age>32</Age> 
     </Profile> 
    </Customer> 

    <Customer> 
     <ID>2</ID> 
     <Name>Dona M. Graduate</Name> 
     <Accounts> 
      <Account> 
       <ID>333</ID> 
       <Name>CCC</Name> 
       <Value>5215</Value>     
      </Account> 
      <Account> 
       <ID>555</ID> 
       <Name>FFF</Name> 
       <Value>6325</Value> 
      </Account> 
     </Accounts> 
     <Profile> 
      <Gender>F</Gender> 
      <Age>36</Age> 
     </Profile> 
    </Customer> 
</Customers> 

期望中的扁平結構應該是這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
<Accounts> 
    <Account> 
    <CustomerID>1</CustomerID> 
    <CustomerName>John Madsen</CustomerName> 
    <ID>111</ID> 
    <Name>AAA</Name> 
    <Value>11234</Value> 
    <Gender>M</Gender> 
    <Age>32</Age> 
    </Account> 
    <Account> 
    <CustomerID>1</CustomerID> 
    <CustomerName>John Madsen</CustomerName> 
    <ID>222</ID> 
    <Name>BBB</Name> 
    <Value>64</Value> 
    <Gender>M</Gender> 
    <Age>32</Age> 
    </Account> 
    <Account> 
    <CustomerID>2</CustomerID> 
    <CustomerName>Dona M. Graduate</CustomerName> 
    <ID>333</ID> 
    <Name>CCC</Name> 
    <Value>5215</Value> 
    <Gender>F</Gender> 
    <Age>36</Age> 
    </Account> 
    <Account> 
    <CustomerID>2</CustomerID> 
    <CustomerName>Dona M. Graduate</CustomerName> 
    <ID>555</ID> 
    <Name>FFF</Name> 
    <Value>6325</Value> 
    <Gender>F</Gender> 
    <Age>36</Age> 
    </Account> 

我使用下面的XSL代碼:

<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:template match="/"> 
    <Accounts> 
     <xsl:for-each select="Customers/Customer/Accounts/Account"> 
      <Account> 
       <xsl:apply-templates select="ancestor::Customer/*[not(*)]"/> 
       <xsl:copy-of select="*" /> 

       <xsl:copy-of select="following::Profile/*"/> 
      </Account>     
     </xsl:for-each> 
    </Accounts> 
</xsl:template> 

<xsl:template match="Customer/*[not(*)]"> 
    <xsl:element name="{concat('Customer', name())}"> 
     <xsl:copy-of select="@*|node()"/> 
    </xsl:element> 
</xsl:template> 

但是,結果我得到的是這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
<Accounts> 
    <Account> 
    <CustomerID>1</CustomerID> 
    <CustomerName>John Madsen</CustomerName> 
    <ID>111</ID> 
    <Name>AAA</Name> 
    <Value>11234</Value> 
    <Gender>M</Gender> 
    <Age>32</Age> 
    <Gender>F</Gender> 
    <Age>36</Age> 
    </Account> 
    <Account> 
    <CustomerID>1</CustomerID> 
    <CustomerName>John Madsen</CustomerName> 
    <ID>222</ID> 
    <Name>BBB</Name> 
    <Value>64</Value> 
    <Gender>M</Gender> 
    <Age>32</Age> 
    <Gender>F</Gender> 
    <Age>36</Age> 
    </Account> 
    <Account> 
    <CustomerID>2</CustomerID> 
    <CustomerName>Dona M. Graduate</CustomerName> 
    <ID>333</ID> 
    <Name>CCC</Name> 
    <Value>5215</Value> 
    <Gender>F</Gender> 
    <Age>36</Age> 
    </Account> 
    <Account> 
    <CustomerID>2</CustomerID> 
    <CustomerName>Dona M. Graduate</CustomerName> 
    <ID>555</ID> 
    <Name>FFF</Name> 
    <Value>6325</Value> 
    <Gender>F</Gender> 
    <Age>36</Age> 
    </Account> 

注意的是,第一個節點有兩個性別及兩個年齡節點,什麼情況是,關鍵字以下::是不是限制它self到當前Customer節點中的後續節點,它將採用整個文檔中的所有follwing節點。

所以我的問題是,我怎麼能限制下面的::關鍵字?還是有另一種方法將配置文件子節點複製到每個帳戶節點中?

感謝 拉菲Asraf

回答

0

您可以父Accounts元素,而不是過於寬泛的使用following-sibling::Profile - 對於這個特殊的病例選擇following::Profile

<xsl:copy-of select="../following-sibling::Profile/*"/> 

xsltransform.net demo

+0

謝謝!我知道有以下兄弟關鍵字,但我沒有想到select會接受../語法。 – sirpadk

+0

@sirpadk對於這種特殊情況只是'parent :: *'或'parent :: Accounts'的縮寫版本 – har07