【问题标题】:Passing XML when foreach loop can't be entered due to colons由于冒号而无法进入foreach循环时传递XML
【发布时间】:2014-07-29 18:12:53
【问题描述】:

在你击落我之前,请给我一分钟。我已经在 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. 我可以循环提要以获取数字
  2. 使用 file_get_contents($var) 我收到此错误

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

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

  4. 我尝试将冒号替换为下划线,但出现了 #2 的错误。
  5. 我尝试了 Stack Overflow 中某处提到的 DOM 方法。
  6. 我尝试过 Stack Overflow 上提到的 SimpleXML 方法。

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

任何帮助都会非常感激,因为我正在扯掉我的头发而且我没有咖啡了!

非常感谢,

马丁

附:对于将其标记为重复的人,我理解你的推理,但我无法理解其他线程中的答案,所以我不得不问一个新的。感谢您的耐心等待,我是社区的新手。

线程 Simple XML - Dealing With Colons In Nodes 没有处理顶部标签无法被 foreach 解析的事实

foreach ($feed-&gt;item as $item)

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

【问题讨论】:

    标签: php xml rss feed


    【解决方案1】:

    冒号将命名空间前缀与本地节点名称分开。这是一个引用 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"
    }
    

    【讨论】:

    • 非常感谢您抽出宝贵时间回复。我会试一试,然后回复你。非常感谢!
    • 当我使用 file_get_content($feed_url) 来获取我的 XML/RSS 文件时,这是一种享受。谢谢!
    猜你喜欢
    • 2021-08-22
    • 1970-01-01
    • 2014-04-19
    • 2017-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多