2012-04-20 33 views
2

我正在處理XSLT轉換。我有一個源文件,其中有一些名爲tag的標籤。在未指定出現順序時處理XSLT中的子標籤

考慮我的源xml是這樣的。

<ABC> 
    <Name>Some Name </Name> 
    <ID>Some ID</ID> 
    <Address>Some Address</Address> 
    <Place>Some Place</Place> 
    <ID>Some ID</ID> 
    <Name>Some Name </Name> 
    <Name>Some Name </Name>  

</ABC> 

規則:

ABC is parent Tag which has 4 child tags. Name, ID, Address, Place. 
    These child tags can occur many times and in any ordrer. 
    Upon reading the tag , I want to change the name of the tag, and do some processing on the value present in the tag. 
    The input XML may have child tags in any order, and many times. 
    I want to write a common XSLT which will read the child tags in the order in which they occur, and display them as given under. 

我要顯示這樣的輸出。

 <Frame:Name> 
        <text>Some Name</text> 
     </Frame:Name> 
    <Frame:ID> 
        <text>Some ID</text> 
     </Frame:ID> 
     <Frame:ADdrress> 
        <text>Some Address</text> 
     </Frame:Address> 
     <Frame:Place> 
        <text>Some Place</text> 
     </Frame:Place> 
    <Frame:ID> 
        <text>Some ID</text> 
     </Frame:ID> 
     <Frame:Name> 
        <text>Some Name</text> 
     </Frame:Name> 
     <Frame:Name> 
        <text>Some Name</text> 
     </Frame:Name> 

我完全感到它是如何完成的。

如果源XML中子元素的出現順序發生變化,它也應該反映在輸出XML中。

有人可以分享評論。

謝謝。

+1

你能分享你的XSLT代碼嗎?如果它看起來不錯,那麼我們可以根據您的要求進行修改。我們可以設計一個新的代碼,但是如果你發佈代碼,你可以知道你的錯誤 – 2012-04-20 10:43:23

+1

在想要的結果中,你錯過了最後一個'Name'元素之一。請改正。 – 2012-04-20 12:38:43

+0

更正..謝謝你 – Patan 2012-04-20 13:13:26

回答

1

的XSLT的辦法來解決這些問題是通過使用模板。其結果是更簡單,更短的和可以理解的代碼,通常沒有任何xsl:choosexsl:whenxsl:otherwisexsl:ifxsl:for-each

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:Frame="some:undefined namespace"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:template match="/*"> 
    <t><xsl:apply-templates/></t> 
</xsl:template> 

<xsl:template match="*/*"> 
    <xsl:element name="Frame:{name()}" namespace="some:undefined namespace"> 
     <text><xsl:apply-templates /></text> 
    </xsl:element> 
</xsl:template> 
</xsl:stylesheet> 

當這種變換所提供的XML文檔應用:

<ABC> 
    <Name>Some Name </Name> 
    <ID>Some ID</ID> 
    <Address>Some Address</Address> 
    <Place>Some Place</Place> 
    <ID>Some ID</ID> 
    <Name>Some Name </Name> 
    <Name>Some Name </Name> 
</ABC> 

想要的,正確的結果產生

<t xmlns:Frame="some:undefined namespace"> 
    <Frame:Name> 
     <text>Some Name </text> 
    </Frame:Name> 
    <Frame:ID> 
     <text>Some ID</text> 
    </Frame:ID> 
    <Frame:Address> 
     <text>Some Address</text> 
    </Frame:Address> 
    <Frame:Place> 
     <text>Some Place</text> 
    </Frame:Place> 
    <Frame:ID> 
     <text>Some ID</text> 
    </Frame:ID> 
    <Frame:Name> 
     <text>Some Name </text> 
    </Frame:Name> 
    <Frame:Name> 
     <text>Some Name </text> 
    </Frame:Name> 
</t> 
+0

謝謝你的信息。我可以對每個元素的數據做一些操作嗎?因爲,它直接更改標籤的名稱。請澄清。 – Patan 2012-04-20 13:02:40

+0

@muzimil:是的,在匹配模板中可以執行任何額外的處理。請爲你的新問題提出一個新問題。目前的問題有一個完整的解決方案 - 正如在這個答案中提供的。 – 2012-04-20 13:06:59

+0

我想要捕獲每個標記中的文本並調用其他一些模板。你可以說,如果可能的話,我會發佈一個問題。 – Patan 2012-04-20 13:11:21

0

基於jeevan的建議。

<xsl:template match="ABC" > 
    <ABC> 
     <xsl:for-each select ="child::*"> 
     <xsl:choose> 
      <xsl:when test="name()='Name'"> 
      <xsl:element name="Frame:Name"> 
       <xsl:apply-templates select="."/> 
      </xsl:element> 
      </xsl:when> 

      <xsl:when test="name()='ID'"> 
      <Frame:ID> 
       <xsl:apply-templates select="."/> 
      </Frame:ID> 
      </xsl:when> 
      <xsl:when test="name()='Address'"> 
      <Frame:Address> 
       <xsl:apply-templates select="."/> 
      </Frame:Address> 
      </xsl:when> 

      <xsl:when test="name()='Place'"> 
      <Frame:Place> 
       <xsl:apply-templates select="."/> 
      </Frame:Place> 
      </xsl:when> 
    </xsl:choose> 
     </xsl:for-each> 

+0

你可能有興趣看到一個解決方案,是短三倍:) – 2012-04-20 12:34:57

+0

可怕的代碼。切勿使用xsl:選擇開啓元素名稱。這是模板規則的用途。 – 2012-04-20 13:54:11