3

我有这个来自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"]');
4

1 回答 1

4

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"]');

这是一个现场演示,显示结果计数为 1,并带有更正的命名空间。


为了尝试给出权威的解释,请考虑以下XML规范中的命名空间摘录:

前缀提供了限定名称的名称空间前缀部分,并且必须与名称空间声明中的名称空间 URI 引用相关联 [...] 注意前缀仅用作名称空间名称的占位符。

与前缀元素或属性名称对应的扩展名称具有前缀绑定到的 URI 作为其命名空间名称 [...]

默认命名空间声明适用于其范围内的所有无前缀元素名称。

如果作用域中存在默认命名空间声明,则对应于无前缀元素名称的扩展名称将默认命名空间的 URI 作为其命名空间名称。如果范围内没有默认命名空间声明,则命名空间名称没有值。[...] 在所有情况下,本地名称 [...] 与无前缀名称本身相同。

该元素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和“本地名称” Sender

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

于 2013-09-01T21:35:26.067 回答