当foreach循环由于冒号而无法输入时传递XML


Passing XML when foreach loop can't be entered due to colons

在你拒绝我之前,给我一分钟。我已经在SO中寻找答案-这是问题

我有一个外部XML/RDF文件,必须用大致如下的结构解析

<?xml version="1.0" encoding="UTF-8"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
 xmlns:rss="http://purl.org/rss/1.0/"
 xmlns:os="http://a9.com/-/spec/opensearch/1.1/"
 xmlns:dc="http://purl.org/dc/elements/1.1/"
 xmlns:dcterms="http://purl.org/dc/terms/"
 xmlns:bibo="http://purl.org/ontology/bibo/">
 <rss:channel rdf:about="http://domain.com/feed/">
  <rss:link rdf:resource="http://domain.com/feed/items.rss" />
  <rss:title>Search Results</rss:title>
  <os:startIndex>0</os:startIndex>
  <os:itemsPerPage>10</os:itemsPerPage>
  <os:totalResults>13</os:totalResults>
  <rss:items rdf:resource="urn:unique-identifier" />
 </rss:channel>
 <rss:item rdf:about="http://domain.com/items/123456">
  <rss:link>http://domain.com/items/123456</rss:link>
  <rss:title>Book Title</rss:title>
  <rss:description>Random Book Description</rss:description>
  <dc:creator>First Name Last Name, 1901</dc:creator>
  <dcterms:language rdf:datatype="http://purl.org/dc/terms/ISO639-2">eng</dcterms:language>
  <dc:format>Book</dc:format>
  <dc:publisher>London : Publisher</dc:publisher>
  <dc:date>2009</dc:date>
  <bibo:isbn>1234567890</bibo:isbn>
  <bibo:eanucc13>1234567890</bibo:eanucc13>
  <dcterms:identifier>1234567890</dcterms:identifier>
 </rss:item>
</rdf:RDF>

好的,这就是XML文件。以下是我所知道的

  1. 我可以循环feed以获得数字
  2. 使用file_get_contents($var)我得到这个错误

    Warning: simplexml_load_file(): I/O warning : failed to load external entity

  3. 我不能使用foreach($rss->item as $item),因为项目本身有一个冒号。

  4. 我已经尝试用下划线替换冒号和错误从#2出现。
  5. 我已经尝试了一个DOM方法提到的堆栈溢出某处。
  6. 我已经尝试了SimpleXML方法提到的堆栈溢出。

我所要做的就是循环rss:items并提取下面的项目。

我真的很感激任何帮助,因为我正在撕裂我的头发,我没有咖啡了!

谢谢你,

马丁

注:对于将此标记为副本的人,我理解您的推理,但我无法理解其他线程中的答案,所以我不得不问一个新的。谢谢你的耐心,我是新来的社区。

线程Simple XML -处理节点中的冒号没有处理top标签不能被foreach

解析的事实

foreach ($feed->item as $item)

在此提要中$feed->item不存在,因为它是$feed->rss::item,这是无效的语法。谢谢。

名称空间前缀与本地节点名称之间用冒号分隔。这是一个引用xmlns:rss定义的别名。因此,像rss:channel这样的名称可以读为{http://purl.org/rss/1.0/}:channel

要使用DOMXpath对象读取具有名称空间的XML,需要注册自己的前缀。这样就可以解析Xpath表达式中的前缀。

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('rss', 'http://purl.org/rss/1.0/');
$result = [];
foreach ($xpath->evaluate('//rss:item') as $item) {
  $result = [
    'title' => $xpath->evaluate('string(rss:title)', $item),
    'link' => $xpath->evaluate('string(rss:link)', $item)
  ];
}
var_dump($result);

输出:https://eval.in/173016

array(2) {
  ["title"]=>
  string(10) "Book Title"
  ["link"]=>
  string(30) "http://domain.com/items/123456"
}