如何在不使用PHP进行迭代的情况下按属性选择xml元素?

我有http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml的XML

<?xml version="1.0" encoding="UTF-8"?>
<gesmes:Envelope xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
    <gesmes:subject>Reference rates</gesmes:subject>
    <gesmes:Sender>
        <gesmes:name>European Central Bank</gesmes:name>
    </gesmes:Sender>
    <Cube>
        <Cube time='2013-08-23'>
            <Cube currency='USD' rate='1.3355'/>
            <Cube currency='GBP' rate='0.85910'/>
            <Cube currency='HUF' rate='298.98'/>
        </Cube>
    </Cube>
</gesmes:Envelope>

(我出于示范目的删除了一些值)

我想获取转换率,比方说,使用PHP的GBP.

HI可以使用simplexml这样加载它:

$XML=simplexml_load_file("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");

    foreach($XML->Cube->Cube->Cube as $rate){
...

但是我想在不迭代的情况下获得价值,我真的不想使用正则表达式…

我尝试了类似的方法,但没有成功:

$sxe=simplexml_load_file("http://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");

$sxe->registerXPathNamespace('c', 'http://www.gesmes.org/xml/2002-08-01');
$result = $sxe->xpath('//c:Cube[@currency="USD"]');

解决方法:

Cube元素不在http://www.gesmes.org/xml/2002-08-01名称空间中,该名称空间已被赋予gesmes前缀,它们在默认名称空间中,即http://www.ecb .int / vocabulary / 2002-08-01 / eurofxref.

因此,而不是:

$sxe->registerXPathNamespace('c', 'http://www.gesmes.org/xml/2002-08-01');
$result = $sxe->xpath('//c:Cube[@currency="USD"]');

您需要注册另一个名称空间:

$sxe->registerXPathNamespace('c', 'http://www.ecb.int/vocabulary/2002-08-01/eurofxref');
$result = $sxe->xpath('//c:Cube[@currency="USD"]');

这是带有更正名称空间的a live demo showing a result count of 1.

要尝试对此进行权威解释,请考虑以下Namespaces in XML规范摘录:

The Prefix provides the namespace prefix part of the qualified name, and MUST be associated with a namespace URI reference in a namespace declaration […] Note that the prefix functions only as a placeholder for a namespace name.

The expanded name corresponding to a prefixed element or attribute name has the URI to which the prefix is bound as its namespace name […]

A default namespace declaration applies to all unprefixed element names within its scope.

If there is a default namespace declaration in scope, the expanded name corresponding to an unprefixed element name has the URI of the default namespace as its namespace name. If there is no default namespace declaration in scope, the namespace name has no value. […] In all cases, the local name is […] the same as the unprefixed name itself.

元素Cube没有前缀,因此我们寻找范围内的默认名称空间声明.到达最外层元素,我们发现xmlns =“ http://www.ecb.int/vocabulary/2002-08-01/eurofxref”,因此Cube元素的“名称空间名称”是URI http:// www. ecb.int/vocabulary/2002-08-01/eurofxref,“本地名称”为Cube.

如果我们改用gesmes:Sender元素,则会看到它具有前缀gesmes,因此我们将寻找该前缀的定义.找到xmlns:gesmes =“ http://www.gesmes.org/xml/2002-08-01”,我们可以得出结论,“扩展名称”具有“命名空间名称” http://www.gesmes.org/ xml / 2002-08-01,以及“本地名称”发件人.

为了在XPath中使用这些“命名空间名称”,我们必须分配要在XPath表达式中使用的前缀,这些前缀不必与实际文档中的前缀相对应.在这种情况下,我们选择为命名空间http://www.ecb.int/vocabulary/2002-08-01/eurofxref分配前缀c,以便表达式// c:Cube将匹配任何带有“命名空间”的元素http://www.ecb.int/vocabulary/2002-08-01/eurofxref的名称”和Cube的“本地名称”.

上一篇:PHP简单HTML DOM解析器-RSS中的链接元素


下一篇:PHP SimpleXML XPath获取下一个父节点