Как остановить зацикливание в XML dom при разборе PHP

У меня есть примерно такой код:

<?xml version="1.0" encoding="UTF-8"?>
<Personlist xmlns="http://example.org">
    <Person>
        <Name>Louis</Name>
        <Address>
            <StreetAddress>Somestreet</StreetAddress>
            <PostalCode>00001</PostalCode>
            <CountryName>Finland</CountryName>
        </Address>
    </Person>
    <Person>
        <Name>Rakshith</Name>
        <Address>
            <StreetAddress>Somestreet</StreetAddress>
            <PostalCode>00001</PostalCode>
            <CountryName>Finland</CountryName>
        </Address>
    </Person>
    <Person>
        <Name>Steve</Name>
        <Address>
            <StreetAddress>Someotherstreet</StreetAddress>
            <PostalCode>43400</PostalCode>
            <CountryName>Sweden</CountryName>
        </Address>
     </Person>
 </Personlist>

Как остановить зацикливание, если имя «Ракшит» найдено при разборе xml dom. А в простом синтаксическом анализаторе xml мы можем напрямую получить доступ к n-му элементу, например $xml->Person[0]->Name. Но в XML dom, насколько я знаю, нам нужно разобрать сам foreach. Есть ли такой способ, который бы соответствовал моему требованию.

заранее спасибо


person Community    schedule 04.03.2014    source источник
comment
Я думаю, вам нужен анализатор саксофона для этого...   -  person eric.itzhak    schedule 04.03.2014
comment
Спасибо за быстрый ответ @eric.itzhak. Раньше я использовал simple_xml_parser(). Из-за неопределенных объектов, предложенных одним из экспертов на этом форуме, я переключился на xml dom. Теперь вы предлагаете мне парсер саксофона, теперь я немного запутался с этими вещами, какой из них мне выбрать. Я немного новичок в XML. Не могли бы вы помочь мне с этим, потому что в веб-сервисах XML, от которых мы зависим, всегда будут отсутствовать некоторые теги от одной к другой детали, что приводит к неопределенному типу объекта и останавливает выполнение. Какой, по вашему мнению, лучший синтаксический анализатор XML для обработки этого? Спасибо   -  person    schedule 04.03.2014
comment
Я сам не эксперт, но, насколько я знаю, вы не можете остановить парсеры dom с вашим условием, поэтому парсеры sax для... дело в том, что и simple_xml_parser, и тот, на который вы, по-видимому, переключились, являются парсерами dom, где весь XML создается в памяти перед использованием, в то время как концепция парсеров sax заключается в том, что он основан на событиях, где вы на самом деле не создаете его в памяти, а выполняете итерацию по нему, не знаете, какой из них лучше использовать для вас , но прочитайте о различиях: stackoverflow.com/questions/6828703/   -  person eric.itzhak    schedule 04.03.2014


Ответы (1)


Если вы используете DOM. Вы можете использовать Xpath, чтобы выбрать только узлы, которые вы хотите повторить:

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);
$xpath->registerNamespace('ns1', 'http://example.org');

$persons = $xpath->evaluate('/ns1:Personlist/ns1:Person[ns1:Name = "Rakshith"]');
foreach ($persons as $person) {
  var_dump(
    $xpath->evaluate('string(ns1:Name)', $person),
    $xpath->evaluate('string(ns1:Address/ns1:CountryName)', $person)
  );
}

Вывод: https://eval.in/110336

string(8) "Rakshith"
string(7) "Finland"

Xpath довольно мощный. Вы используете выражение с условиями для описания списка узлов (это может быть список с одним узлом или пустой список). Если вы делаете что-то, что подразумевает скалярное значение, используется первый узел в списке.

В вашем примере вы определяете пространство имен XML по умолчанию. Здесь нет пространства имен XML по умолчанию в xpath, вы регистрируете свой собственный префикс и используете его. В примере используется «ns1».

Выражение Xpath выбирает элемент документа Personlist

/ns1:Personlist

затем его Person дочерних элементов:

/ns1:Personlist/ns1:Person

ограничивает этот список узлами с дочерним элементом Name со значением "Rakshith"

/ns1:Personlist/ns1:Person[ns1:Name = "Rakshith"]

Это всегда будет возвращать список (пустой, если ничего не найдено), поэтому можно перебирать этот список без дальнейшей проверки.

Внутри выражения цикла используются контекст, указанный в качестве второго аргумента для оценки. Функция string() преобразует список результатов в строковое значение.

person ThW    schedule 04.03.2014