首先发布在这里!
好的..我的联系人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">anyone123452154@gmail.com</ContactData>
<Type type="String">4</Type>
</item>
<item>
<ContactData type="String">+5554444444</ContactData>
<Type type="String">2</Type>
</item>
</contact>
如您所见,类型4是电子邮件,类型1是电话号码,类型2是传真,类型3是手机号码。
所以这是我的情景:
我(可能)需要遍历所有这些节点。检查是否有电话号码(最高优先级)并选择它。如果没有电话号码,我们需要检查手机号码(第二高优先级)。如果手机号码不可用,我们选择电子邮件(或我们什么都不做)。我怎样才能实现它?
谢谢..
答案 0 :(得分:2)
与Tim C的答案类似,但附加要求仅返回Type 1,Type 3或Type 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>
答案 1 :(得分:1)
实现此目标的一种方法是使用 xsl:for-each 简单地遍历项元素,并对的值进行排序输入元素。然后你可以简单地选择第一个元素。
这是完整的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:for-each 更改为以下内容:
<xsl:for-each select="item[Type != '2'][ContactData != '']">
或者,如果您只想说明手机,手机或电子邮件,那么您可以执行以下操作
<xsl:for-each select="item[Type = '1' or Type = '3' or Type = '4'][ContactData != '']">
答案 2 :(得分: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">anyone123452154@gmail.com</ContactData>
<Type type="String">4</Type>
</item>
<item>
<ContactData type="String">+5554444444</ContactData>
<Type type="String">2</Type>
</item>
</contact>
评估XPath表达式并将选定的节点复制到输出中:
+4444444444
答案 3 :(得分: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()