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 は携帯電話番号です。

だからここに私のシナリオがあります:

私は(おそらく)これらすべてのノードを反復処理する必要があります。電話番号(最優先)があるかどうかを確認して選択します。電話番号がない場合は、携帯電話番号を確認する必要があります (2 番目に高い優先度)。携帯電話番号が利用できない場合は、電子メールを選択します (または何もしません)。どうすれば達成できますか?

ありがとう..

4

4 に答える 4

2

ティム C の回答に似ていますが、タイプ 1、タイプ 3、またはタイプ 4 のアイテムのみを返すという追加の要件があります。

XSLT1.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

これを実現する 1 つの方法は、 Type要素の値で並べ替えを行い、 xsl:for-eachを使用してitem要素を単純に反復処理することです。次に、最初の要素を選択するだけです。

ここに完全な 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 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 に答える
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 に答える