PHP - Получить конкретные поля из XML-файла - PullRequest
0 голосов
/ 14 ноября 2018

со следующим частичным кодом я получаю данные XML через API

$xmlObj = new SimpleXMLElement($result);

$xmlObj->registerXPathNamespace( 'N', 'http://www.loc.gov/MARC21/slim');

$sfield = $xmlObj->xpath( '//N:datafield[@tag="550"]/N:subfield[@code="a"]' );

Это работает.Но теперь я хочу отфильтровать получаемые данные

  1. Я просто хочу получить данные с code = "a" из tag = "550", где значение для code = "i"is "Funktion"

  2. Я просто хочу получить данные с code = "a" из tag = "550", где значение для code = "i" не является "Funktion".

Как я могу это сделать с помощью xpath?

Пример XML с "Funktion"

<datafield tag="550" ind1=" " ind2=" ">
<subfield code="a">Text</subfield>
<subfield code="4">funk</subfield>
<subfield code="4">http://d-nb.info/standards/elementset/gnd#functionOrRole</subfield>
<subfield code="w">r</subfield>
<subfield code="i">Funktion</subfield>
</datafield>

Пример XML без "Funktion"

<datafield tag="550" ind1=" " ind2=" ">
<subfield code="0">(DE-101)041251733</subfield>
<subfield code="0">(DE-588)4125173-8</subfield>
<subfield code="0">http://d-nb.info/gnd/4125173-8</subfield>
<subfield code="a">Grafiker</subfield>
<subfield code="4">beru</subfield>
<subfield code="4">http://d-nb.info/standards/elementset/gnd#professionOrOccupation</subfield>
<subfield code="w">r</subfield>
<subfield code="i">Beruf</subfield>
</datafield>

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Вы можете вкладывать и комбинировать условия. Итак, шаг за шагом:

  • Выбрать любой datafield элемент
    //N:datafield
  • ... с атрибутом tag, то есть 550
    //N:datafield[@tag="550"]
  • ... и с дочерним элементом subfield
    //N:datafield[@tag="550" and N:subfield]
  • ... с атрибутом code со значением i
    //N:datafield[@tag="550" and N:subfield[@code="i"]]
  • ... текстовое содержание этого subfield должно быть Funktion
    //N:datafield[@tag="550" and N:subfield[@code="i"] = "Funktion"]
  • ... и получите subfield ребенка datafield
    //N:datafield[@tag="550" and N:subfield[@code="i"] = "Funktion"]/N:datafield
  • ... с атрибутом code со значением a
    //N:datafield[@tag="550" and N:subfield[@code="i"] = "Funktion"]/N:datafield[@code="a"]

Для второго выражения вы можете просто использовать not() для этого конкретного выражения.

  • ... текстовое содержание этого subfield должно быть Funktion
    //N:datafield[@tag="550" and not(N:subfield[@code="i"] = "Funktion")]

Пробелы в выражениях Xpath в основном игнорируются (не раньше, чем ведущий /). Таким образом, вы можете обернуть и сделать отступы, чтобы сделать их более читабельными.

Составьте:

$xml = <<<'XML'
<foo xmlns="http://www.loc.gov/MARC21/slim">
  <datafield tag="550">
    <subfield code="a">Text</subfield>
    <subfield code="i">Funktion</subfield>
  </datafield>
  <datafield tag="550">
    <subfield code="a">Grafiker</subfield>
    <subfield code="i">Beruf</subfield>
  </datafield>
</foo>
XML;

$element = new SimpleXMLElement($xml);
$element->registerXPathNamespace( 'N', 'http://www.loc.gov/MARC21/slim');

$expression = '//N:datafield[
  @tag="550" and N:subfield[@code="i"] = "Funktion"
]/N:subfield[@code="a"]';

foreach ($element->xpath($expression) as $field) {
    var_dump((string)$field);
}

echo str_repeat('-', 25), "\n";

$expression = '//N:datafield[
  @tag="550" and not(N:subfield[@code="i"] = "Funktion")
]/N:subfield[@code="a"]';

foreach ($element->xpath($expression) as $field) {
    var_dump((string)$field);
}

Выход:

string(4) "Text" 
------------------------- 
string(8) "Grafiker"
0 голосов
/ 14 ноября 2018

Используйте этот запрос xpath

$sfield = $xmlObj->xpath('//N:datafield[@tag="550"][subfield[@code="a"]][subfield[@code="i"][text()="Funktion"]]');

Обратите внимание, что [text()="Funktion"] элемент фильтра имеет текст Funktion

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...