Как оценить xpath для конкретного именного пространства с помощью phpstorm?

Европейский центральный банк предлагает 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='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’s Evaluate XPath... особенность.

Все же это, казалось, не распознало пространство имен; поэтому он не нашел соответствия //Cube,

Оцените окно XPath

Я также пытался использовать Show unique XPathи для меня это отображает

/gesmes:Envelope/e:Cube/e:Cube/e:Cube/@rate

Тем не менее, используя это для оценки урожайности без отклика.

Я предполагаю, что у меня это неправильно настроено (поскольку я пытался редактировать контекст, но я не знал, что я делал).

Изменить контекст Xpath

Как мне установить правильное пространство имен?

2

Решение

Вы использовали префикс e для пространства имен http://www.ecb.int/vocabulary/2002-08-01/eurofxref в выражении Xpath, но настроил префикс 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"]=> ...
2

Другие решения

Вам нужно будет указать XPath, какие пространства имен связаны с какими префиксами, или установить пространство имен по умолчанию для нефиксированных имен в вашем выражении. Не все языки хоста поддерживают настройку этого параметра.

В PHPStorm вы можете сделать это, нажав на кнопку Изменить контекст ..., см документацию.

Если по какой-то причине вы не можете установить это правильно, вы можете использовать запрос, используя локальное имя имени, ваш запрос становится:

/*[local-name() = 'Envelope']
/*[local-name() = 'Cube']
/*[local-name() = 'Cube']
/*[local-name() = 'Cube']/@rate

Не идеально, но это будет работать.

⑴ Любое имя XML содержит локальную часть, которая является частью после двоеточия или всего имени, если нет двоеточия, часть префикса, которая является частью перед двоеточием, и часть пространства имен, которая является пространством имен, префиксом которого является связаны с Имя XML детерминировано определяется локальным именем и пространством имен, префикс не имеет значения.

0

По вопросам рекламы [email protected]