如何使用 phpstorm 评估特定命名空间的 xpath?
How to evaluate xpath for a specific namesapce using phpstorm?
欧洲中央银行提供 XML document for currency exchange rates 依赖于欧元。
<?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='2015-09-17'>
<Cube currency='USD' rate='1.1312'/>
<Cube currency='JPY' rate='136.76'/>
<Cube currency='BGN' rate='1.9558'/>
...
</Cube>
</Cube>
</gesmes:Envelope>
我已将此 XML 文件存储为货币汇率提供商的测试用例,因为我想为其编写解析器。
我想使用 phpstorm 的 Evaluate XPath...
功能。
但它似乎无法识别命名空间;所以它没有找到 //Cube
.
的任何匹配项
我也试过使用Show unique XPath
,对我来说它显示
/gesmes:Envelope/e:Cube/e:Cube/e:Cube/@rate
但是没有人用它来评估收益。
我想我配置有误(因为我试图编辑上下文,但我不知道自己在做什么)。
如何设置正确的命名空间?
您需要告诉 XPath 哪些命名空间绑定到哪些前缀,或者为表达式中的无前缀名称设置默认命名空间。并非所有宿主语言都支持设置此项。
在 PHPStorm 中,您可以通过单击按钮 编辑上下文...、see documentation.
来完成此操作
如果由于某种原因,你不能正确设置它,你可以使用一个名称的本地名称进行查询⑴,你的查询将变为:
/*[local-name() = 'Envelope']
/*[local-name() = 'Cube']
/*[local-name() = 'Cube']
/*[local-name() = 'Cube']/@rate
不理想,但它会起作用。
⑴ 任何XML名称都包含局部部分,即冒号之后的部分,如果没有冒号则为全名,前缀部分即前面的部分冒号和命名空间部分,这是前缀绑定到的命名空间。 XML 名称由其本地名称及其名称空间确定性定义,前缀无关紧要。
您在 Xpath 表达式中为命名空间 http://www.ecb.int/vocabulary/2002-08-01/eurofxref
使用了前缀 e
,但为其配置了前缀 c
。
您不需要在 PHP 中为其编写解析器。只需使用 DOM + Xpath。
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('gesmes', 'http://www.gesmes.org/xml/2002-08-01');
$xpath->registerNamespace('e', 'http://www.ecb.int/vocabulary/2002-08-01/eurofxref');
$time = $xpath->evaluate('string(/gesmes:Envelope/e:Cube/e:Cube/@time)');
$rates = [];
foreach ($xpath->evaluate('/gesmes:Envelope/e:Cube/e:Cube/e:Cube') as $cube) {
$rates[$cube->getAttribute('currency')] = $cube->getAttribute('rate');
}
var_dump($time, $rates);
输出:
string(10) "2015-09-22"
array(31) {
["USD"]=>
string(6) "1.1155"
["JPY"]=>
string(6) "133.75"
["BGN"]=>
string(6) "1.9558"
["CZK"]=>
string(6) "27.057"
["DKK"]=> ...
欧洲中央银行提供 XML document for currency exchange rates 依赖于欧元。
<?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='2015-09-17'>
<Cube currency='USD' rate='1.1312'/>
<Cube currency='JPY' rate='136.76'/>
<Cube currency='BGN' rate='1.9558'/>
...
</Cube>
</Cube>
</gesmes:Envelope>
我已将此 XML 文件存储为货币汇率提供商的测试用例,因为我想为其编写解析器。
我想使用 phpstorm 的 Evaluate XPath...
功能。
但它似乎无法识别命名空间;所以它没有找到 //Cube
.
我也试过使用Show unique XPath
,对我来说它显示
/gesmes:Envelope/e:Cube/e:Cube/e:Cube/@rate
但是没有人用它来评估收益。
我想我配置有误(因为我试图编辑上下文,但我不知道自己在做什么)。
如何设置正确的命名空间?
您需要告诉 XPath 哪些命名空间绑定到哪些前缀,或者为表达式中的无前缀名称设置默认命名空间。并非所有宿主语言都支持设置此项。
在 PHPStorm 中,您可以通过单击按钮 编辑上下文...、see documentation.
来完成此操作如果由于某种原因,你不能正确设置它,你可以使用一个名称的本地名称进行查询⑴,你的查询将变为:
/*[local-name() = 'Envelope']
/*[local-name() = 'Cube']
/*[local-name() = 'Cube']
/*[local-name() = 'Cube']/@rate
不理想,但它会起作用。
⑴ 任何XML名称都包含局部部分,即冒号之后的部分,如果没有冒号则为全名,前缀部分即前面的部分冒号和命名空间部分,这是前缀绑定到的命名空间。 XML 名称由其本地名称及其名称空间确定性定义,前缀无关紧要。
您在 Xpath 表达式中为命名空间 http://www.ecb.int/vocabulary/2002-08-01/eurofxref
使用了前缀 e
,但为其配置了前缀 c
。
您不需要在 PHP 中为其编写解析器。只需使用 DOM + Xpath。
$document = new DOMDocument();
$document->loadXml($xml);
$xpath = new DOMXpath($document);
$xpath->registerNamespace('gesmes', 'http://www.gesmes.org/xml/2002-08-01');
$xpath->registerNamespace('e', 'http://www.ecb.int/vocabulary/2002-08-01/eurofxref');
$time = $xpath->evaluate('string(/gesmes:Envelope/e:Cube/e:Cube/@time)');
$rates = [];
foreach ($xpath->evaluate('/gesmes:Envelope/e:Cube/e:Cube/e:Cube') as $cube) {
$rates[$cube->getAttribute('currency')] = $cube->getAttribute('rate');
}
var_dump($time, $rates);
输出:
string(10) "2015-09-22"
array(31) {
["USD"]=>
string(6) "1.1155"
["JPY"]=>
string(6) "133.75"
["BGN"]=>
string(6) "1.9558"
["CZK"]=>
string(6) "27.057"
["DKK"]=> ...