2012-06-13 296 views
1

選擇一個XML節點我有以下XML,這種需要使用XSLT解析,基於優先級

<PERSONS> 
    <PERSON> 
     <TYPE>F</TYPE> 
     <NAME>ABC</NAME> 
    </PERSON> 
    <PERSON> 
     <TYPE>A</TYPE> 
     <NAME>XYA</NAME> 
    </PERSON> 
    <PERSON> 
     <TYPE>S</TYPE> 
     <NAME>AFF</NAME> 
    </PERSON> 
    <PERSON> 
     <TYPE>B</TYPE> 
     <NAME>HHH</NAME> 
    </PERSON> 
</PERSONS> 

在上述XML,PERSON類型可以來以任何順序和我需要的輸出如下,

<SELECTED> 
    <NAME>TEXT</NAME> 
</SELECTED> 

的規則是,我們需要基於以下優先顯示的名稱, A,F,S

如果A型不存在,檢查F型和顯示如果存在名稱或顯示類型S名稱。

也有可能是其他類型,如B和C會在輸入XML,但我們需要忽略那些類型,只有優先進入A,F和S

由於提前, 威爾遜。

回答

0

您的訂單似乎是按字母順序排列的,但由於您沒有這樣說,我認爲這不是一個可靠的預期。

這是怎麼回事?

http://www.xmlplayground.com/cMOOBF

如果確實順序是按字母可靠,倒不如先您的節點進行排序,而不是使用複雜的謂詞,因爲我有。

+0

我知道你喜歡鏈接到xmlplayground.com的僅鏈接答案,但你能明確地發佈你的樣式表嗎?雖然沒有反對它的SO政策,但在meta網站上對此事進行了一次討論,幾乎普遍認爲這是不好的做法,值得贊成。 –

+0

當然 - 我沒有意識到這是JS問題的一大堆問題,我期待JSFiddle會議。有時候只需要代碼(對於簡單的答案),但有時也很好地展現它的實際效果。在這種情況下,我會開始做這兩件事。 – Utkanos

0

假設你TYPE是按字母順序排序,你可以使用

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:template match="PERSONS"> 
     <xsl:for-each select="PERSON"> 
      <xsl:sort select="TYPE" order="ascending" /> 
      <xsl:if test="position() = 1"> 
       <SELECTED> 
        <NAME> 
         <xsl:value-of select="./NAME" /> 
        </NAME> 
       </SELECTED> 
      </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 

</xsl:stylesheet> 
+0

感謝Filburt的快速反應,但排序不會工作我的情況,因爲它有可能來其他類型也' B'和' C'但這些東西我需要忽略,只有優先事項去A,F和S. – Wilz

+0

Filburt,我在問題中也包含了相同的內容,對不起,我沒有提過它。 – Wilz

1

這種轉變

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

<xsl:param name="pOrder" select="'AFS'"/> 

<xsl:template match="/*"> 
    <xsl:for-each select="PERSON[contains($pOrder, TYPE)]"> 
    <xsl:sort select="string-length(substring-before($pOrder, TYPE))" data-type="number"/> 

    <xsl:if test="position() = 1"> 
      <SELECTED> 
       <xsl:copy-of select="NAME"/> 
      </SELECTED> 
    </xsl:if> 
    </xsl:for-each> 
</xsl:template> 
</xsl:stylesheet> 

時所提供的XML文檔應用:

<PERSONS> 
    <PERSON> 
     <TYPE>F</TYPE> 
     <NAME>ABC</NAME> 
    </PERSON> 
    <PERSON> 
     <TYPE>A</TYPE> 
     <NAME>XYA</NAME> 
    </PERSON> 
    <PERSON> 
     <TYPE>S</TYPE> 
     <NAME>AFF</NAME> 
    </PERSON> 
    <PERSON> 
     <TYPE>B</TYPE> 
     <NAME>HHH</NAME> 
    </PERSON> 
</PERSONS> 

產生想要的,正確的結果

<SELECTED> 
    <NAME>XYA</NAME> 
</SELECTED> 

如果$pOrder參數例如改變到

<xsl:param name="pOrder" select="'SAF'"/> 

然後再次通緝,正確的結果產生:

<SELECTED> 
    <NAME>AFF</NAME> 
</SELECTED> 

說明

Type的字符串值的接近程度使用排序按優先級類型字符串開始排序。

+0

這真的很酷! – Filburt

+0

@Filburt:不客氣。 –