2012-08-24 85 views
1

第一篇文章在這裏!遍歷數組並根據優先級進行選擇

確定..我有一個接觸XML如下:

<contact> 
    <item> 
    <ContactData type="String">+4444444444</ContactData> 
    <Type type="String">1</Type> 
    </item> 
    <item> 
    <ContactData type="String">+9999999999</ContactData> 
    <Type type="String">3</Type> 
    </item> 
    <item> 
    <ContactData type="String">[email protected]</ContactData> 
    <Type type="String">4</Type> 
    </item> 
    <item> 
    <ContactData type="String">+5554444444</ContactData> 
    <Type type="String">2</Type> 
    </item> 
</contact> 

正如你可以看到類型4是一個電子郵件,類型1是一個電話號碼,類型2是一個傳真和3型是一個手機號碼。

因此,這裏是我的情況:

我(可能)需要通過這些節點進行迭代。檢查是否有電話號碼(最高優先級)並選擇它。如果沒有電話號碼,我們需要檢查手機號碼(第二高優先級)。如果手機號碼不可用,我們選擇電子郵件(或者我們什麼都不做)。我怎樣才能實現它?

謝謝..要實現這一

+2

有在貼出的問題使用CDATA部分沒有任何意義。這只是與實際問題無關,它掩蓋了沒有任何好處。我將幫助編輯。 –

+0

不知道在哪裏寫這個...但是你真是太棒了!!!非常感謝你.. !!我很感激...我使用Tim C的解決方案.. – user994612

回答

1

的一種方法是簡單地在項目迭代元素與的xsl:for-每個,與上類型元素的值排序。然後你可以簡單地選擇第一個元素。

以下是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" indent="yes"/> 

    <xsl:template match="contact"> 
     <xsl:for-each select="item[ContactData != '']"> 
     <xsl:sort select="Type" order="ascending" /> 
     <xsl:if test="position() = 1"> 
      <xsl:value-of select="ContactData" /> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

當適用於您的示例XML,下面是輸出

+4444444444 

如果你要空出的電話號碼,它應該返回的手機號碼代替。也將其刪除,並返回電子郵件地址。

編輯:如果您需要排除的傳真號碼,你可以在XSL發生變化: - 每個以下幾點:

<xsl:for-each select="item[Type != '2'][ContactData != '']"> 

或者,如果你想明確地規定只電話,手機或電子郵件,那麼你可以做以下

<xsl:for-each select="item[Type = '1' or Type = '3' or Type = '4'][ContactData != '']"> 
+0

好的..謝謝你的回答..但是我也有一個類型'2'的傳真...比什麼?所以更具體地說,我只想檢查電話和移動設備,並根據最高優先級進行選擇。 – user994612

+0

嗯,在你的問題中提及這些事情總是有幫助的!如果您可以使用完整的詳細信息編輯您的問題,那麼我確信擴展答案會更容易。謝謝! –

2

蒂姆C'S答案相似,但只有返回類型1,類型3或類型4個項目的額外要求。

XSLT 1。0

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

    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="contact"> 
     <xsl:variable name="vContacts"> 
      <xsl:apply-templates select="item[Type='1' or Type='3' or Type='4']"> 
       <xsl:sort select="Type"/> 
      </xsl:apply-templates>       
     </xsl:variable> 
     <results><xsl:value-of select="$vContacts/item[1]/ContactData"/></results> 
    </xsl:template> 

</xsl:stylesheet> 

輸出

<results>+4444444444</results> 
0

這可以用一個XPath表達式來獲得 - 你真的完全不需要XSLT:

(/*/item[Type = 1] 
    | 
    /*[not(item[Type = 1])]/item[Type = 3] 
    | 
    /*[not(item[Type = 1 or Type = 3])]/item[Type = 4] 
    ) 
    /ContactData/text() 

基於XSLT的驗證

<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:template match="/"> 
    <xsl:copy-of select= 
    "(/*/item[Type = 1] 
    | 
    /*[not(item[Type = 1])]/item[Type = 3] 
    | 
    /*[not(item[Type = 1 or Type = 3])]/item[Type = 4] 
    ) 
    /ContactData/text()"/> 
</xsl:template> 
</xsl:stylesheet> 

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

<contact> 
    <item> 
    <ContactData type="String">+4444444444</ContactData> 
    <Type type="String">1</Type> 
    </item> 
    <item> 
    <ContactData type="String">+9999999999</ContactData> 
    <Type type="String">3</Type> 
    </item> 
    <item> 
    <ContactData type="String">[email protected]</ContactData> 
    <Type type="String">4</Type> 
    </item> 
    <item> 
    <ContactData type="String">+5554444444</ContactData> 
    <Type type="String">2</Type> 
    </item> 
</contact> 

XPath表達式求值和所選擇的(多個)節點被複制到輸出:

+4444444444 
0

或者,如果您有XPath 2.0,則可以按照其優先級順序編寫您想要的類型(1,3,4),遍歷類型和選擇第一個是有:

/contact/(for $i in (1,3,4) return item[Type = $i])[1]/ContactData/text() 

或與展開的循環:

/contact/(*[Type = 1], *[Type = 3], *[Type = 4])[1]/ContactData/text()