3

同じ情報が異なるノードの子として表示されるXMLがあります。そのような :

<root>
<category id=1>
        <product id="ABC123" >

              <sizes>
                    <size name="S"/>
                <size name="M"/>
                <size name="L"/>
                <size name="XL"/>
                <size name="2XL"/>
                <size name="3XL"/>
              </sizes>
            </product>

                 </products>
           </category>
<category id=2>
        <products>
        <product id="ABC123" >

              <sizes>
                    <size name="S"/>
                <size name="M"/>
                <size name="L"/>
                <size name="XL"/>
                <size name="2XL"/>
                <size name="3XL"/>
              </sizes>
            </product>

          <product id="PPP543" >

              <sizes>
                    <size name="S"/>
                <size name="M"/>
                <size name="L"/>
                <size name="XL"/>
              </sizes>
            </product>

                 </products>
           </category>

私の目標は、製品ID ABC123のサイズを選択し、それらを配列として格納することです。私が持っている現在のコードは:

$arrTest=array();


    foreach($xml->xpath('//root/category/products/product[@id= "'.$productCall.'" ]/sizes/size') as $size){

              array_push($arrTest, $size["name"]);
      }

$productCallは私が探しているIDです。この場合はABC123です。

出力はS、M、L、XL、2XL、3XL、S、M、L、XL、2XL、3XLです。見つかった2つのエントリを読み取っていることを意味します。foreachループを考えると、これを期待していましたが、最初の結果の出力を取得する方法を見つけることができないようです。[0]と[1]を追加してみました:

$y=$xml->xpath('//root/category/products/product[@id= "'.$productCall.'" ][1]/sizes/size');

[0]は何も返しません、[1]は私がすでに得ているのと同じ結果を返します。

これまでxpathを実際に使用したことがないので、これが基本的なものを見逃したり、考えすぎたりするという単純な問題であることを願っています。

4

1 に答える 1

0

使用:

(/*/*//product[@id='ABC123']/sizes)[1]/size

または使用

((/*/*/product | /*/*/products/product)/sizes)[1]/size

XSLT ベースの検証:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
  <xsl:copy-of select=
    "(/*/*//product[@id='ABC123']/sizes)[1]/size"/>
========
  <xsl:copy-of select=
    "((/*/*/product | /*/*/products/product)/sizes)[1]/size"/>

 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメントに適用されると(整形式のドキュメントに修正した後):

<root>
    <category id="1">
        <product id="ABC123" >
            <sizes>
                <size name="S"/>
                <size name="M"/>
                <size name="L"/>
                <size name="XL"/>
                <size name="2XL"/>
                <size name="3XL"/>
            </sizes>
        </product>
    </category>
    <category id="2">
        <products>
            <product id="ABC123" >
                <sizes>
                    <size name="S"/>
                    <size name="M"/>
                    <size name="L"/>
                    <size name="XL"/>
                    <size name="2XL"/>
                    <size name="3XL"/>
                </sizes>
            </product>
            <product id="PPP543" >
                <sizes>
                    <size name="S"/>
                    <size name="M"/>
                    <size name="L"/>
                    <size name="XL"/>
                </sizes>
            </product>
        </products>
    </category>
</root>

2 つの XPath 式が評価され、それぞれから選択されたノードが視覚的に適切に区切られて出力にコピーされます。どちらも正しいです。

<size name="S"/>
<size name="M"/>
<size name="L"/>
<size name="XL"/>
<size name="2XL"/>
<size name="3XL"/>
========
  <size name="S"/>
<size name="M"/>
<size name="L"/>
<size name="XL"/>
<size name="2XL"/>
<size name="3XL"/>

//: 2 番目の XPath 式は、疑似演算子を使用しないため、(十分に大きなドキュメントで) より効率的であると期待しています。

于 2012-10-26T18:49:14.130 に答える