2016-10-28 70 views
0

我是XSLT新手,目前正在使用xslt將輸入XML上的遞歸函數轉換爲目標XML。使用XSLT遞歸

  1. 輸入XML:
<?xml version="1.0" encoding="UTF-8"?> 
<referenced> 
<name>XYZ</name> 
<LOCK_STATUS>2</LOCK_STATUS> 
    <reference> 
     <name>MC</name> 
     <LOCK_STATUS>2</LOCK_STATUS> 
    </reference> 
    <reference> 
     <name>MC1</name> 
     <LOCK_STATUS>2</LOCK_STATUS> 
    </reference> 
    <reference> 
     <name>List</name> 
     <LOCK_STATUS>2</LOCK_STATUS> 
      <reference> 
       <name>entList</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
      </reference> 
      <reference> 
       <name>ist</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
      </reference> 
      <reference> 
       <name>WumentList</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
        <reference> 
         <name>WumentList</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </reference> 
        <reference> 
         <name>WumentList</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </reference> 
      </reference> 
    </reference> 
     <reference> 
     <name>entList</name> 
     <LOCK_STATUS>2</LOCK_STATUS> 
      <reference> 
       <name>entList</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
      </reference> 
      <reference> 
       <name>ist</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
      </reference> 
      <reference> 
       <name>WumentList</name> 
       <LOCK_STATUS>2</LOCK_STATUS> 
      </reference> 
    </reference> 
</referenced> 
  • 目標XML我想要實現:
  • <?xml version="1.0" encoding="UTF-8"?> 
    <children> 
    <name>XYZ</name> 
    <LOCK_STATUS>2</LOCK_STATUS> 
        <children> 
         <name>MC</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </children> 
        <children> 
         <name>MC1</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </children> 
        <children> 
         <name>DocumentList</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
          <children> 
           <name>entList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>ist</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>WumentList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
            <children> 
             <name>WumentList</name> 
             <LOCK_STATUS>2</LOCK_STATUS> 
            </children> 
            <children> 
             <name>WumentList</name> 
             <LOCK_STATUS>2</LOCK_STATUS> 
            </children> 
          </children> 
        </children> 
        <children> 
         <name>st</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
          <children> 
           <name>entList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>ist</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>WumentList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
        </children> 
    </children> 
    
  • XSLT我寫的函數:
  • <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" encoding="utf-8"/> 
         <xsl:template match="/"> 
         <xsl:apply-templates select="reference"/> 
         </xsl:template> 
         <xsl:template match="reference[reference]"> 
         <xsl:apply-templates select="reference"/> 
         </xsl:template> 
         <xsl:template match="reference"> 
         <children> 
          <name> 
          <xsl:value-of select="name" /> 
          </name> 
          <LOCK_STATUS> 
          <xsl:value-of select="LOCK_STATUS" /> 
          </LOCK_STATUS> 
         </children> 
        </xsl:template> 
    </xsl:stylesheet> 
    

    不知何故,我無法用我寫的xslt實現目標XML。

    Hi Tim,

    感謝您對此的幫助。試圖瞭解你提供的代碼spinet和教程我去互聯網瞭解更多:)

    不在我的情況下,我不必重命名引用引用。

    將如何XSLT變化,如果預期輸出XML應該出現這樣的你是你的根元素被命名爲referenced,但在你的第一個模板是尋找一個根元素

    <?xml version="1.0" encoding="UTF-8"?> 
    <nodeInfo> 
    <name>XYZ</name> 
    <LOCK_STATUS>2</LOCK_STATUS> 
        <children> 
         <name>MC</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </children> 
        <children> 
         <name>MC1</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
        </children> 
        <children> 
         <name>DocumentList</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
          <children> 
           <name>entList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>ist</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>WumentList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
            <children> 
             <name>WumentList</name> 
             <LOCK_STATUS>2</LOCK_STATUS> 
            </children> 
            <children> 
             <name>WumentList</name> 
             <LOCK_STATUS>2</LOCK_STATUS> 
            </children> 
          </children> 
        </children> 
        <children> 
         <name>st</name> 
         <LOCK_STATUS>2</LOCK_STATUS> 
          <children> 
           <name>entList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>ist</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
          <children> 
           <name>WumentList</name> 
           <LOCK_STATUS>2</LOCK_STATUS> 
          </children> 
        </children> 
    </nodeInfo> 
    
    +0

    我已經修改了我的答案,但是如果您沒有爲您的問題添加第二個輸入XML,而是將原始輸入XML修改爲您想要的內容,將會很清楚。謝謝! –

    回答

    1

    的一個問題的reference

    <xsl:template match="/"> 
         <xsl:apply-templates select="reference"/> 
        </xsl:template> 
    

    /符號的頂級文檔節點,這是您的XML(你的情況referenced)的單根元素的父匹配。

    您也不需要第二個匹配reference[reference]的模板,因爲這會跳過任何reference元素與子元素reference,這不是您想要的。

    但是如果你想遞歸,你只需要一個xsl:apply-templates添加到您的模板匹配reference

    試試這個XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" encoding="utf-8"/> 
    
        <xsl:template match="referenced"> 
         <nodeInfo> 
          <name> 
          <xsl:value-of select="name" /> 
          </name> 
          <LOCK_STATUS> 
          <xsl:value-of select="LOCK_STATUS" /> 
          </LOCK_STATUS> 
          <xsl:apply-templates select="reference" /> 
         </nodeInfo> 
        </xsl:template> 
    
        <xsl:template match="reference"> 
         <children> 
          <name> 
          <xsl:value-of select="name" /> 
          </name> 
          <LOCK_STATUS> 
          <xsl:value-of select="LOCK_STATUS" /> 
          </LOCK_STATUS> 
          <xsl:apply-templates select="reference" /> 
         </children> 
        </xsl:template> 
    </xsl:stylesheet> 
    

    更妙的是,利用identity template,這對減少了你需要做的工作(因爲看起來你所要做的只是將referenced重命名爲nodeInfo,referencechildren):

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes" encoding="utf-8"/> 
    
        <xsl:template match="@*|node()"> 
         <xsl:copy> 
          <xsl:apply-templates select="@*|node()"/> 
         </xsl:copy> 
        </xsl:template> 
    
        <xsl:template match="referenced"> 
         <nodeInfo> 
          <xsl:apply-templates /> 
         </nodeInfo> 
        </xsl:template> 
    
        <xsl:template match="reference"> 
         <children> 
          <xsl:apply-templates /> 
         </children> 
        </xsl:template> 
    </xsl:stylesheet> 
    
    +0

    身份模板是否有助於複製引用到nodeInfo中的所有內容,並引用了子節點,只要它們的結構相同? – Nis

    +0

    是的。身份模板用於複製您不想更改的所有節點和屬性。在這種情況下,您正在使用'children'替換'reference',但保留所有後代節點,因此身份模板將爲您處理這些內容。 –

    +0

    但在我的結尾它沒有發生。輸入xml已被修改了一點,現在引用有一些額外的派生節點。在xslt被應用之後(標識模板),在輸出xml中也沒有看到。我可以重新發布輸入xml嗎? – Nis