2013-02-26 100 views
0

好的,我正在編輯原始帖子。我想我通過替換原始XML的名稱標籤嘗試了一下。不管怎麼說,這裏是從原始文件的摘錄:在使用XSL將XML轉換爲XML時需要幫助

<EMPLOYEE_LIST> 
    <EMPLOYEES> 
     <EMPLOYEE> 
     <EMPID>650000</EMPID> 
     <FIRST_NAME>KEITH</FIRST_NAME> 
     <MIDDLE_NAME>HUTCHINSON</MIDDLE_NAME> 
     <LAST_NAME>ROGERS</LAST_NAME> 
     <EMP_TYPE></EMP_TYPE> 
     <EMP_REF_ID>500000</EMP_REF_ID> 
     <JOINED_ON>2001-10-06</JOINED_ON> 
     <COMMENTS>Miscellanous Comments</COMMENTS> 
     <NATIONALITY> 
      <VALUE>American</VALUE> 
     </NATIONALITY> 
     <EMP_AKA> 
      <AKA_NAME>Danny</AKA_NAME> 
     </EMP_AKA> 
     <EMP_AKA> 
      <AKA_NAME>Dan</AKANAME> 
     </EMP_AKA> 
     <EMP_AKA> 
      <AKA_NAME>Ray</AKA_NAME> 
     </EMP_AKA> 
     <EMP_ADDR> 
      <STREET> </STREET> 
      <CITY> </CITY> 
      <STATE> </STATE> 
      <ZIP> </ZIP> 
      <COUNTRY> </COUNTRY> 
     </EMPLOYEE> 
    </EMPLOYEES> 
</EMPLOYEE_LIST> 

,我與上面的XML面臨的問題是,我無法找到一個方法來適應多個AKA(又稱)在一個單一的財產屬性和我使用這種轉變的XSL如下:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 
    <xsl:strip-space elements="*"/> 
     <xsl:template match="/EMPLOYEE_LIST"> 
      <employees> 
       <xsl:apply-templates select="EMPLOYEES/node()"/> 
      </employees>   
     </xsl:template> 

     <xsl:template match="EMPLOYEE"> 
     <employee> 
      <xsl:apply-templates select="*"/> 
     </employee> 
     </xsl:template> 

     xsl:template match="EMPLOYEE/EMPID"> 
     <emp_id> 
      <xsl:value-of select="."/> 
     </emp_id> 
     </xsl:template> 

      <xsl:template match="EMPLOYEE/FIRST_NAME"> 
     <f_name> 
      <xsl:value-of select="."/> 
     </f_name> 
     </xsl:template> 

     <xsl:template match="EMPLOYEE/MIDDLE_NAME"> 
      <m_name> 
       <xsl:value-of select="."/> 
      </m_name> 
     </xsl:template> 

     <xsl:template match="EMPLOYEE/LAST_NAME"> 
      <l_name> 
       <xsl:value-of select="."/> 
      </l_name> 
     </xsl:template> 
     . 
     . 
     . 
     . 
     . 
     <xsl:template match="EMPLOYEE/EMP_AKA"> 
     <aka_list> 
      <xsl:for-each select="AKA_NAME"> 
       <aka> 
        <xsl:for-each select="."> 
         <xsl:apply-templates/> 
        </xsl:for-each> 
       </aka> 
      </xsl:for-each> 
     </aka_list> 
    </xsl:template> 
</xsl:stylesheet> 

當應用到我的XML上述給出的XSL提供了以下的輸出:

<?xml version="1.0" encoding="UTF-8"?> 
<employees> 
     <employee> 
     <emp_id>111345</emp_id> 
     <f_name>KEITH</f_name> 
     <m_name>HUTCHINSON</m_name> 
     <l_name>ROGERS</l_name> 
     <aka_list> 
      <aka>Danny</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Dan</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Ray</aka> 
     </aka_list> 
     </employee> 
</employees> 

而這並不是我牛逼rying實現,因爲我需要在以下格式的數據:

<?xml version="1.0" encoding="UTF-8"?> 
<employees> 
     <employee> 
     <emp_id>111345</emp_id> 
     <f_name>KEITH</f_name> 
     <m_name>HUTCHINSON</m_name> 
     <l_name>ROGERS</l_name> 
     <aka_list> 
      <aka>Danny</aka> 
      <aka>Dan</aka> 
      <aka>Ray</aka> 
     </aka_list> 
     </employee> 
</employees 

有什麼辦法來實現這一目標?展望未來,XML中的元素數量巨大,例如AKA_NAME。

  <aka_list> 
      <aka>Danny</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Dan</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Ray</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Danny_2</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Dan_2</aka> 
     </aka_list> 
     <aka_list> 
      <aka>Ray_2</aka> 
     </aka_list> 

改造應該只發揚頂部5和第六個應該被截斷等:

  <aka_list> 
      <aka>Danny</aka> 
      <aka>Dan</aka> 
      <aka>Ray</aka> 
      <aka>Danny_2</aka> 
      <aka>Dan_2</aka> 
     </aka_list> 
+0

您發佈的輸出與XSLT模板(輸出中沒有AKA_LIST元素)不匹配。 – 2013-02-26 11:04:32

+0

' JOHN FILTER'用AKA打開關閉ALIAS,驗證錯誤..確定您的輸入XML。 – 2013-02-26 11:59:51

+0

我不明白,你的代碼中有'',但你的輸出中有''和''?究竟你想要哪一個? – 2013-02-26 12:11:55

回答

2

UPDATE:用於完整的XML解決方案。

我試圖用XSLT模板中的註釋來解釋解決方案。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 

    <!-- Ignore text nodes by default --> 
    <xsl:template match="text()" /> 

    <!-- Transform tag name EMPLOYEES to employees --> 
    <xsl:template match="EMPLOYEES"> 
     <employees> 
      <xsl:apply-templates select="*" /> 
     </employees> 
    </xsl:template> 

    <!-- Transform tag name EMPLOYEE to employee --> 
    <xsl:template match="EMPLOYEE"> 
     <employee> 
      <xsl:apply-templates select="*" /> 
     </employee> 
    </xsl:template> 

    <!-- Transform tag name EMPID to emp_id --> 
    <xsl:template match="EMPID"> 
     <emp_id> 
      <xsl:value-of select="." /> 
     </emp_id> 
    </xsl:template> 

    <!-- Transform tag name FIRST_NAME to f_name --> 
    <xsl:template match="FIRST_NAME"> 
     <f_name> 
      <xsl:value-of select="." /> 
     </f_name> 
    </xsl:template> 

    <!-- Transform tag name MIDDLE_NAME to m_name --> 
    <xsl:template match="MIDDLE_NAME"> 
     <m_name> 
      <xsl:value-of select="." /> 
     </m_name> 
    </xsl:template> 

    <!-- Transform tag name LAST_NAME to l_name --> 
    <xsl:template match="LAST_NAME"> 
     <l_name> 
      <xsl:value-of select="." /> 
     </l_name> 
    </xsl:template> 

    <!-- When encounter the first EMP_AKA element, print itself and its following 
     siblings with the same name within an aka_list element --> 
    <xsl:template match="EMP_AKA[1]"> 
     <aka_list> 
      <xsl:apply-templates select="AKA_NAME|following-sibling::EMP_AKA/AKA_NAME" mode="print"/> 
     </aka_list> 
    </xsl:template> 

    <!-- Transform tag name EMP_AKA to aka --> 
    <xsl:template match="AKA_NAME" mode="print"> 
     <aka> 
      <xsl:value-of select="." /> 
     </aka> 
    </xsl:template> 

</xsl:stylesheet> 

更新2:如果你不想使用模板模式,因爲AKA_NAME將被其他地方匹配,並以同樣的方式處理,你可以通過這些的替換最後兩個模板:

<!-- When encounter the first EMP_AKA element, print itself and its following 
    siblings with the same name within an aka_list element --> 
<xsl:template match="EMP_AKA[1]"> 
    <aka_list> 
     <xsl:apply-templates select="AKA_NAME|following-sibling::EMP_AKA/AKA_NAME" /> 
    </aka_list> 
</xsl:template> 

<!-- Exclude all EMP_AKA elements (except the first one because 
    the previous template has higher precedence than this one) --> 
<xsl:template match="EMP_AKA" /> 

<!-- Transform tag name EMP_AKA to aka --> 
<xsl:template match="AKA_NAME"> 
    <aka> 
     <xsl:value-of select="." /> 
    </aka> 
</xsl:template> 

<xsl:template match="EMP_AKA" /> 

此代碼產生與上一個相同的輸出。


UPDATE 3:OP詢問如何限制輸出AKA_NAME元件的數量。這是基於更新2的解決方案只是

<xsl:template match="EMP_AKA[1]"> 
    <aka_list> 
     <xsl:apply-templates select="AKA_NAME|following-sibling::EMP_AKA[position() &lt; 5]/AKA_NAME" /> 
    </aka_list> 
</xsl:template> 

<!-- Transform tag name EMP_AKA to aka --> 
<xsl:template match="AKA_NAME"> 
    <aka> 
     <xsl:value-of select="." /> 
    </aka> 
</xsl:template> 

<xsl:template match="EMP_AKA" /> 

原來的答案

的OP編輯的職位,並徹底改變了XML文件替換最後一個模板從更新2。以下是我以前的回答(似乎並沒有刪除它)。

如果你試圖把所有的< AKA>元素爲< AKA_LIST>元素(這是不明確的,因爲你發佈的不匹配轉換的輸出),那麼你可以使用下面的轉換:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes"/> 

    <!-- Just for demo --> 
    <xsl:template match="text()" /> 

    <!-- Match PERSON: create the list --> 
    <xsl:template match="PERSON"> 
     <AKA_LIST> 
      <xsl:apply-templates select="NAME/AKA" /> 
     </AKA_LIST> 
    </xsl:template> 

    <!-- Outputs the AKA element, changing the tag name --> 
    <xsl:template match="AKA"> 
     <aka> 
      <xsl:value-of select="." /> 
     </aka> 
    </xsl:template> 

</xsl:stylesheet> 

哪些改變你的源XML到:

<AKA_LIST> 
    <aka>ROSE PETAL</aka> 
    <aka>JOHN FILTER</aka> 
</AKA_LIST> 
+0

不錯的解決方案巴勃羅,只使用模板匹配和應用模板。 +1 – Peter 2013-02-26 11:17:46

+0

''不需要..因爲這不是重新命名的要求。另外一個更好的做法是覆蓋身份模板.. – 2013-02-26 12:25:47

+0

嗯,我們不會知道直到OP在他的文章中澄清他正在嘗試做什麼。我假設他正在嘗試做什麼,併爲此發佈瞭解決方案。我不認爲我們可以假設它是否或者不需要重命名(想象他將在此之後使用XML Schema來驗證輸出XML) – 2013-02-26 13:00:55

1

你的XSLT代碼實際上混淆了,因爲你有一個像<AKA_LIST>一些標籤。所以,我會通過輸入和輸出的XML示例:這裏是XSLT代碼

<?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="PERSON"> 
    <xsl:copy> 
     <xsl:apply-templates select="NAME[1]"/> 
    </xsl:copy> 
    </xsl:template> 

    <xsl:template match="NAME"> 
    <xsl:copy> 
     <xsl:apply-templates select="/PEOPLE/PERSON/NAME/AKA"/> 
    </xsl:copy> 
    </xsl:template> 


</xsl:stylesheet> 

輸入XML:

<?xml version="1.0" encoding="utf-8"?> 
<PEOPLE> 
    <PERSON> 
    <NAME> 
     <REFERENCE>GOOD</REFERENCE> 
     <AKA>ROSE PETAL</AKA> 
     </NAME> 
    <NAME> 
     <REFERENCE>GOOD</REFERENCE> 
     <AKA>JOHN FILTER</AKA> 
     </NAME> 
    </PERSON> 
</PEOPLE> 

輸出:

<?xml version="1.0" encoding="utf-8"?> 
<PEOPLE> 
    <PERSON> 
    <NAME> 
     <AKA>ROSE PETAL</AKA> 
     <AKA>JOHN FILTER</AKA> 
    </NAME> 
    </PERSON> 
</PEOPLE> 

說明:

<xsl:template match="@*|node()"> ...... 

從輸入上面的代碼拷貝標記輸出AS IS *,其他模板匹配重寫這個..

<xsl:template match="PERSON"> ...... 

上面的代碼拷貝只有一個<NAME> TAG(第一)到輸出..

<xsl:template match="NAME"> 
    <xsl:copy> 
     <xsl:apply-templates select="/PEOPLE/PERSON/NAME/AKA"/> 
     ...... 

上面的代碼副本<NAME>下的所有<AKA>標籤。由於我們僅複製一個<NAME>標記,所有<AKA>標記出現在<NAME>