2012-08-24 73 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()