代码之家  ›  专栏  ›  技术社区  ›  Rick Scolaro

使用PHP和SimpleXML解析带有命名空间的APFeeds XML

  •  1
  • Rick Scolaro  · 技术社区  · 9 年前

    我无法从XML中获取以下信息:

    <apcm:Property Name="EntitlementMatch" Id="urn:publicid:ap.org:product:41664" Value="AP Top News" />
    <apcm:Property Name="EntitlementMatch" Id="urn:publicid:ap.org:product:42430" Value="AP Top News - International - Stories" />
    <apcm:Property Name="EntitlementMatch" Id="urn:publicid:ap.org:package:100518" Value="AP Top News Package" />
    

    具体来说,我需要“ID”和“Value”字段。

    以下是XML的主要部分:

    <?xml version="1.0" encoding="utf-8" ?>
    <feed xmlns="http://www.w3.org/2005/Atom" xmlns:apcm="http://ap.org/schemas/03/2005/apcm" xmlns:apnm="http://ap.org/schemas/03/2005/apnm" xmlns:georss="http://www.georss.org/georss" xmlns:o="http://w3.org/ns/odrl/2/">
    ...
    <entry xmlns="http://www.w3.org/2005/Atom">
    ...
    <apcm:ContentMetadata xmlns:apcm="http://ap.org/schemas/03/2005/apcm">
    ...
    <apcm:Property Name="EntitlementMatch" Id="urn:publicid:ap.org:product:41664" Value="AP Top News" />
    <apcm:Property Name="EntitlementMatch" Id="urn:publicid:ap.org:product:42430" Value="AP Top News - International - Stories" />
    <apcm:Property Name="EntitlementMatch" Id="urn:publicid:ap.org:package:100518" Value="AP Top News Package" />
    ...
    </apcm:ContentMetadata>
    </entry>
    </feed>
    

    我一直在看下面的SO帖子,试图找出答案,这篇是迄今为止最有帮助的: Identical nested XML elements with namespaces and PHP

    下面是我正在玩的代码:

        $ns_dc = $feed_entry->children($ns['apcm']);
        echo "APCM children: " . count($ns_dc) . "<br />";
    
        $inner_ns_dc = $feed_entry->children($ns_dc["apcm:Property"]);
        echo "APCM Property Children: " . count($inner_ns_dc) . "<br />";
    
        //$sxe = new SimpleXMLElement($feed_entry);
    
        $sxe = new SimpleXMLElement($feed_entry->asXML());
    
        foreach($sxe->apcm as $item) {
            printf("%s\n", $item);
        }
        $sxe->registerXPathNamespace('apcm', 'http://ap.org/schemas/03/2005/apcm');
        $result = $sxe->xpath('/apcm:Property:*');
    
        echo "Result count: " . count($result) . "<br />";
    
        foreach ($result as $sequenceNumber) {
          echo $sequenceNumber . "<br />";
        }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   The fourth bird    9 年前

    我想你可以注册命名空间,然后使用这个 xpath 表达式来获取元素:

    $elements=$feed_entry->xpath(“//a:entry/apcm:ContentMetadata/apcm:Property”);

    这个 $elements 是一个数组 SimpleXMLElement 可以从中获取 attributes .

    $source = <<<SOURCE
    <?xml version="1.0" encoding="utf-8" ?>
    <feed xmlns="http://www.w3.org/2005/Atom" xmlns:apcm="http://ap.org/schemas/03/2005/apcm"
          xmlns:apnm="http://ap.org/schemas/03/2005/apnm" xmlns:georss="http://www.georss.org/georss"
          xmlns:o="http://w3.org/ns/odrl/2/">
        <entry xmlns="http://www.w3.org/2005/Atom">
            <apcm:ContentMetadata xmlns:apcm="http://ap.org/schemas/03/2005/apcm">
                <apcm:Property Name="EntitlementMatch" Id="urn:publicid:ap.org:product:41664" Value="AP Top News"/>
                <apcm:Property Name="EntitlementMatch" Id="urn:publicid:ap.org:product:42430" Value="AP Top News - International - Stories"/>
                <apcm:Property Name="EntitlementMatch" Id="urn:publicid:ap.org:package:100518" Value="AP Top News Package"/>
            </apcm:ContentMetadata>
        </entry>
    </feed>
    SOURCE;
    
    $feed_entry = simplexml_load_string($source);
    $feed_entry->registerXPathNamespace('a', 'http://www.w3.org/2005/Atom');
    $elements = $feed_entry->xpath('//a:entry/apcm:ContentMetadata/apcm:Property');
    
    foreach ($elements as $element) {
        $id = $element->attributes()->Id->__toString();
        $value = $element->attributes()->Value->__toString();
    
        echo "The Id is: $id and the Value is: $value<br>";
    }
    

    将导致:

    Id为:urn:publicationd:ap。org:product:41664,值为:AP Top 消息

    Id为:urn:publicationd:ap。org:product:42430,值为:AP Top 新闻-国际-故事

    Id为:urn:publicationd:ap。org:package:100518,值为:AP 顶级新闻包

    Demo