0

SimpleXMLを使用してXMLファイルをループし、PreviousノードとNextノードから特定のデータ(具体的にはseries-> displayname属性)を毎回プルしようとしています。

XML構造のサンプルを次に示します。

<comic>
      <id>117</id>
      <index>1</index>
      <mainsection>
        <pagecount>33</pagecount>
        <series>
          <displayname>Amazing Story</displayname>
          <sortname>Amazing Story</sortname>
        </series>
      </mainsection>
</comic>
<comic>
      <id>102</id>
      <index>1</index>
      <mainsection>
        <pagecount>33</pagecount>
        <series>
          <displayname>Fantastic Tale</displayname>
          <sortname>Fantastic Tale</sortname>
        </series>
      </mainsection>
</comic>
<comic>
      <id>85</id>
      <index>1</index>
      <mainsection>
        <pagecount>33</pagecount>
        <series>
          <displayname>The Great Tale</displayname>
          <sortname>The Great Tale</sortname>
        </series>
      </mainsection>
</comic>

そして、これが私がループで使用している構造のサンプルです:

$prevIssue = $comic->xpath('preceding-sibling::*')->mainsection->series->displayname;
$nextIssue = $comic->xpath('following-sibling::*')->mainsection->series->displayname;

echo '
<li class="issue" id="' . $seriesCat . '">
<h3>' . $comicSeriresName . '</h3>
   <div id="details">
   <span id="publisher">' . $comicPublisher . '</span><br>
    The last series was called "' . $prevIssue . '<br>
    The next series is called "' . $nextIssue . '<br>
   </div>
</li>'; 

ただし、「nextIssue」および「prevIssue」変数は機能していません。彼らは空白の結果を返しています。私は何が間違っているのですか?

どんなガイダンスでも大歓迎です。

4

3 に答える 3

2

以下のコードを試してください

$prevIssue_arr = $comic->xpath('preceding-sibling::*[1]');
$prevIssue = (isset($prevIssue_arr[0])) ? $prevIssue_arr[0]->mainsection->series->displayname : '';
$nextIssue_arr = $comic->xpath('following-sibling::*[1]');
$nextIssue = (isset($nextIssue_arr[0])) ? $nextIssue_arr[0]->mainsection->series->displayname : '';

echo ...

[編集]

他の人は、コードが機能しなかった理由をすでに説明しています

1つは、xpath()メソッドがSimpleXMLElementオブジェクトの配列を返すことです。一致するノードが見つからない場合は、空の配列が返されます。

もう1つは、述部がない場合、[1]または[position()=1]ロケーションパスにない場合、先行ノードまたは後続comicノードがすべて返されることです。

または、ロケーションパスを使用して、直後の兄弟から'following-sibling::comic[1]/mainsection/series'必要なノードだけを取得することもできます。series複数のseriesノードがある場合は、位置を指定するか、すべてを返す必要があります。

したがって、このロケーションパスを使用します

$prevIssue_arr = $comic->xpath('preceding-sibling::comic[1]/mainsection/series');
$prevIssue = (isset($prevIssue_arr[0])) ? $prevIssue_arr[0]->displayname : '';
$nextIssue_arr = $comic->xpath('following-sibling::comic[1]/mainsection/series');
$nextIssue = (isset($nextIssue_arr[0])) ? $nextIssue_arr[0]->displayname : '';
于 2012-09-30T09:17:28.077 に答える
2

問題はここにあります:

preceding-sibling::*

先行するすべての兄弟要素を 選択します。

following-sibling::*

次のすべての兄弟要素を選択します。

それぞれ、直前の兄弟または直後の兄弟の1つだけが必要です

preceding-sibling::*[1]

および

following-sibling::*[1]
于 2012-09-30T14:11:12.343 に答える
1

問題の一部は、他の回答で触れられているが明示的に説明されていないように、SimpleXMLオブジェクトに対するほとんどの操作とは異なり、別のSimpleXMLオブジェクトではなく配列->xpath()を返すことです。(これはおそらく、ドキュメント全体から完全に無関係なノードを含む可能性のあるSimpleXMLオブジェクトを回避するためです。)

したがって、配列をオブジェクトとして扱っているため、この行は失敗します。

$prevIssue = $comic->xpath('preceding-sibling::*')->mainsection->series->displayname;

PHP 5.4では、以下が有効な構文です(配列が返された直後に配列にインデックスを付けます)。

$prevIssue = $comic->xpath('preceding-sibling::*')[0]->mainsection->series->displayname; 

ただし、以前のバージョンのPHPの場合、またはXPathが0の結果を返す場合がある場合は、中間変数が必要です。

$prevSiblings = $comic->xpath('preceding-sibling::*');
$prevIssue = (
    ( count($prevSiblings) > 0 )
    ? $prevSiblings[0]->mainsection->series->displayname
    : NULL
);
于 2012-09-30T14:22:53.830 に答える