5
$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/');

私が理解していることから、それらはドキュメント定義のように機能し、特定のXML要素を識別する必要があります。

PHPは実際にそのURLにリクエストを送信し、要素がドキュメント定義に存在するかどうかを確認しますか?

そのURLは404が見つからないページを示しているので:(

$result = $xpath->evaluate('string(//atom:entry[3]/slash:comments)');

<slash>これが、RSSフィードから要素の値を取得しようとしているときに空の文字列を取得する理由でしょうか?

4

4 に答える 4

5
$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/');

私が理解していることから、それらはドキュメント定義のように機能し、特定のXML要素を識別する必要があります。

PHPは実際にそのURLにリクエストを送信し、要素がドキュメント定義に存在するかどうかを確認しますか?

いいえ
。そのURIは、XML語彙を表すXML名前空間を識別します。このような名前空間は、異なる意味を持つ同じ用語を使用して、異なるコンテキストに対処するように設計されています。名前空間を使用すると、単一のXMLファイルに、プレフィックスで修飾された同じ「名前」のタグと属性を含めることができます。たとえば、次のようなxmlドキュメントを作成できます。

<html xmlns="http://www.w3.org/1999/xhtml" 
        xmlns:human="http://sample.xml.com/Human">
  <title>John Smith measures.</title>
  <body>
    <human:name>John</human:name> <human:surname>Smith</human:surname>
    is <human:height unit="feet">6</human:height> feet tall.
  </body>
</html>

このようなコンテンツでは、「human」プレフィックスを使用してhttp://sample.xml.com/Human名前空間の要素をマークし、空の文字列(デフォルトのプレフィックス)を使用してhttp://wwwの要素をマークします。 .w3.org / 1999/xhtml名前空間。これらのURIは名前空間識別子であり、スキーマの場所ではありません( DOCTYPE宣言またはXMLスキーマインスタンスのいずれかで表現できます)。名前空間URIで識別される場所に名前空間の適切なドキュメントを提供することをお勧めしますが、必須ではありません(実際、xhtml名前空間URIは関連するW3Cドキュメントを指しますが、探しているRSS拡張子はそうではありません) 。

ただし、とは両方ともresolveExternalsvalidateOnParseターゲットxmlによって参照されるDTDまたはスキーマ定義のダウンロードに影響を与える可能性がありますが、名前空間のドキュメントには影響を与えないことに注意してください。人間が消費することを目的としているため、パーサーがそのようなドキュメントをダウンロードすることは決してありません。

$result = $xpath->evaluate('string(//atom:entry[3]/slash:comments)');

これが、RSSフィードから要素の値を取得しようとしているときに空の文字列を取得する理由でしょうか?

いいえ。
最初に、ソースxmlに正しいxmlns宣言が含まれていること、および3番目のアトムエントリ<slash:comments>内にノードが含まれていることを確認します( xpathインデックスは1ベースであるため、3番目に注意してください。つまり、各エントリはそれ自体で最初です。親ノード、2番目など)。もしそうなら、私はあなたがアトム名前空間 を登録するのを忘れたのではないかと思います。次のようなものを試してください( DOMXPath :: registerNamespaceドキュメント へのユーザーの貢献から適応)://atom:entry[1]//atom:entry[2]

$doc = new DOMDocument;
$doc->loadXML($xml); // your xml string here
$xpath = new DOMXPath($doc);

$xpath->registerNamespace('atom', "http://www.w3.org/2005/Atom");
$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/');

$result =  $xpath->evaluate('string(//atom:entry[3]/slash:comments)');

これはhttp://codepad.org/JX8RpaKuで実行されているのを見ることができます

実際、修飾されたxpathを使用するには、デフォルトの名前空間も登録する必要があります。

于 2013-04-03T16:16:12.463 に答える
2

複数の質問があります。私はそれらに一つずつ対処しようとします:

$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/');

私が理解していることから、それらはドキュメント定義のように機能し、特定のXML要素を識別する必要があります。

はい、名前空間を持つXMLドキュメントがある場合は常に、各要素を独自の名前空間に含めることができます。

独自の名前空間内の要素にアクセスする場合は、はい、それらを識別するための名前空間が必要です。たとえば、Xpath式内。

PHPでは、XML名前空間はDOMDocumentおよびその他のlibxmlベースのXML拡張機能でサポートされています。

PHPは実際にそのURLにリクエストを送信し、要素がドキュメント定義に存在するかどうかを確認しますか?

いいえ、あなたが与えるコード例の場合:

$xpath->registerNamespace('slash', 'http://purl.org/rss/1.0/modules/slash/');

PHPはそのURLを要求しません。あなたはすでにURLが空である/404を与えることに気づいたので、これが何であるかを理解したいかもしれません。そのURLは実際にはURIです。それが、識別子ロケーターの違いです。

URIピル:URLまたはURNにすることができます

XML名前空間を機能させるには、何も見つける必要はありません。名前空間を特定するだけで済みます。したがって、有効なXML名前空間は任意のURIで表すことができます。たとえば、fantasy:spaceは有効なURIであり、XML名前空間を指定するための要件を完全に満たしています。ただし、ブラウザに入力しても、サーバーの応答は返されません(ブラウザは「ファンタジー」の意味を認識していません)。

したがって、取得した404は、Xpath評価でスラッシュが空になる理由ではありません。

$result = $xpath->evaluate('string(//atom:entry[3]/slash:comments)');

ここで空の文字列を取得する理由は別のものです。Xpath式を参照してください。

string(//atom:entry[3]/slash:comments)

これは、ノードセットの文字列値を要求しています。ノードセットを次のように指定しました。

//atom:entry[3]/slash:comments

PHP DOMDocumentでノードセットの文字列を取得するということは、次のことを意味します。

ノードセットは、ドキュメント順に最初にあるノードセット内のノードの文字列値を返すことによって文字列に変換されます。ノードセットが空の場合、空の文字列が返されます。

ノードは要素であるため、要素ノードの文字列値は次のことを意味します。

要素ノードの文字列値は、要素ノードのすべてのテキストノードの子孫の文字列値をドキュメント順に連結したものです。

したがって、ここで空の文字列を取得する理由は2つあります。ノードセットが空であるか、要素のstring-valueが単なる空の文字列であるかのいずれかです。

count()次の関数を使用して、ノードセット内のノードの数をすばやく知ることができます。

$result = $xpath->evaluate('count(//atom:entry[3]/slash:comments)');

そうすれば、2つのケースのどちらが当てはまるかがわかります。ソースXMLを共有していないので、なぜ具体的には言えませんが、私が推測するように、ノードが含まれていません。ソースを見ると、これを簡単に明らかにする必要があります。

<atom:entry>それまでは、おそらく要素を含まず、要素のみを含むRSS2フィードを解析していると推測できます<item>。私の例を参照してください:

$feed = 'http://hakre.wordpress.com/feed/';

$doc = new DOMDocument();
$doc->load($feed);
$xpath = new DOMXPath($doc);

echo $xpath->evaluate('string(//item[3]/slash:comments)'); # 1

3番目の項目のコメント数として値「1」を出力します。これは、標準のWordpressブログのフィードです。これをインタラクティブな例としてオンラインで公開したので、実際の動作を確認してフィードのURLを入力できます

ところで: XMLをロードしたDOMXPathにオブジェクトを作成する場合、ドキュメントで使用されているプレフィックスがわかっている限り、名前空間URIを登録する必要はありません。これが、この例では名前空間URIを登録しない理由です。

于 2013-04-07T13:39:29.430 に答える
1

名前空間のあるノードのコンテンツを取得したい場合は、getElementsByTagNameNSを試しましたか?

$dom - new DOMDocument($url);
$slashEls = $dom->getElementsbyTagNameNS('slash', 'slash'); // Assuming the element is <slash:slash> in the XML
foreach($slashEls as $slash) {
    // ...
}
于 2012-11-04T00:52:18.707 に答える
1

13歳であるがまだ有用な名前空間のチュートリアルについては、を参照してください。

http://www.jclark.com/xml/xmlns.htm

于 2012-11-04T09:33:08.237 に答える