dongying7847 2015-03-23 20:01
浏览 75
已采纳

命名空间和XPath

I'm exploring XML and PHP, mostly XPath and other parsers.

Here be the xml:

<?xml version="1.0" encoding="UTF-8"?>

<root xmlns:foo="http://www.foo.org/" xmlns:bar="http://www.bar.org">
    <actors>
        <actor id="1">Christian Bale</actor>
        <actor id="2">Liam Neeson</actor>
        <actor id="3">Michael Caine</actor>
    </actors>
    <foo:singers>
        <foo:singer id="4">Tom Waits</foo:singer>
        <foo:singer id="5">B.B. King</foo:singer>
        <foo:singer id="6">Ray Charles</foo:singer>
    </foo:singers>
    <items>
        <item id="7">Pizza</item>
        <item id="8">Cheese</item>
        <item id="9">Cane</item>
    </items>
</root>

Here be my path & code:

$xml = simplexml_load_file('xpath.xml');

$result = $xml -> xpath('/root/actors');

echo '<pre>'.print_r($result,1).'</pre>';

Now, said path returns:

Array
(
    [0] => SimpleXMLElement Object
        (
            [actor] => Array
                (
                    [0] => Christian Bale
                    [1] => Liam Neeson
                    [2] => Michael Caine
                )
        )
)

Whereas a seemingly similar line of code, which I would have though would result in the singers, doesnt. Meaning:

$result = $xml -> xpath('/root/foo:singers');

Results in:

Array
    (
        [0] => SimpleXMLElement Object
            (
            )

    )

Now I would've thought the foo: namespace in this case is a non-issue and both paths should result in the same sort of array of singers/actors respectively? How come that is not the case?

Thank-you!

Note: As you can probably gather I'm quite new to xml so please be gentle.

Edit: When I go /root/foo:singers/foo:singer I get results, but not before. Also with just /root I only get actors and items as results, foo:singers are completely omitted.

  • 写回答

2条回答 默认 最新

  • dpvp56187 2015-03-23 21:59
    关注

    SimpleXML is, for a number of reasons, simply a bad API.

    For most purposes I suggest PHP's DOM extension. (Or for very large documents a combination of it along with XMLReader.)

    For using namespaces in xpath you'll want to register those you'd like to use, and the prefix you want to use them with, with your xpath processor.


    Example:

    $dom = new DOMDocument();
    $dom->load('xpath.xml');
    $xpath = new DOMXPath($dom);
    
    // The prefix *can* match that used in the document, but it's not necessary.
    $xpath->registerNamespace("ns", "http://www.foo.org/");
    
    foreach ($xpath->query("/root/ns:singers") as $node) {
        echo $dom->saveXML($node);
    }
    

    Output:

    <foo:singers>
        <foo:singer id="4">Tom Waits</foo:singer>
        <foo:singer id="5">B.B. King</foo:singer>
        <foo:singer id="6">Ray Charles</foo:singer>
    </foo:singers>
    

    DOMXPath::query returns a DOMNodeList containing matched nodes. You can work with it essentially the same way you would in any other language with a DOM implementation.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 如何用stata画出文献中常见的安慰剂检验图
  • ¥15 c语言链表结构体数据插入
  • ¥40 使用MATLAB解答线性代数问题
  • ¥15 COCOS的问题COCOS的问题
  • ¥15 FPGA-SRIO初始化失败
  • ¥15 MapReduce实现倒排索引失败
  • ¥15 ZABBIX6.0L连接数据库报错,如何解决?(操作系统-centos)
  • ¥15 找一位技术过硬的游戏pj程序员
  • ¥15 matlab生成电测深三层曲线模型代码
  • ¥50 随机森林与房贷信用风险模型