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">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 是手机号码。

所以这是我的场景:

我(可能)需要遍历所有这些节点。检查是否有电话号码(最高优先级)并选择它。如果没有电话号码,我们需要检查手机号码(第二高优先级)。如果手机号码不可用,我们会选择电子邮件(或者我们什么也不做)。我怎样才能实现它?

谢谢..

4

4 回答 4

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>
于 2012-08-24T15:14:26.983 回答
1

实现此目的的一种方法是简单地使用xsl:for-each遍历item元素,并对Type元素的值进行排序。然后你可以简单地选择第一个元素。

这是完整的 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 != '']">
于 2012-08-24T14:00:53.623 回答
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
于 2012-08-25T04:39:46.110 回答
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()
于 2012-08-25T09:55:56.337 回答