PHP — извлечение фрагмента XML из более крупного XML-документа

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

Учитывая этот XML:

<?xml version="1.0" encoding="utf-8"?>
<everyone>
  <guest>
    <name>Joseph Needham</name>
    <age>53</age>
  </guest>
  <guest>
    <name>Lu Gwei-djen</name>
    <age>31</age>
  </guest>
</everyone>

Как мне вернуть именно это:

  <guest>
    <name>Joseph Needham</name>
    <age>53</age>
  </guest>
  <guest>
    <name>Lu Gwei-djen</name>
    <age>31</age>
  </guest>

Мне не нужен объект simplexml, я не хочу ничего преобразовывать, мне не нужны только значения узлов, мне не нужен новый XML-документ с соответствующим заголовком... только этот кусок XML . Не могу использовать внешние библиотеки... ничего, кроме стандартной, средней установки PHP. Как извлечь одно из другого?

Моя лучшая догадка? Используйте DomDocument, чтобы каким-то образом получить имена и содержимое узлов, а затем перестроить то, что я хочу, используя цикл foreach и повторяя различные имена и значения узлов, включая окончания строк, для правильного форматирования всего. Тем не менее, кажется, что это может быть удивительно неуклюжим. Я подозреваю, что есть более простой способ сделать это, поэтому я хочу узнать, знает ли кто-нибудь здесь, в stackoverflow, что это за способ (или может сказать мне, что на самом деле НЕ существует более простого способа). Заранее спасибо.


person Lothar    schedule 15.12.2009    source источник
comment
Если у вас есть гарантии форматирования вашего ввода, разве вы не хотите просто удалить первые две строки и удалить последнюю строку?   -  person catchmeifyoutry    schedule 15.12.2009


Ответы (4)


Что-то вроде этого (используя XPath - если у вас есть другой способ получить список гостевых элементов, вы можете использовать его) должно помочь.

$xml = '';
$xpath = new DOMXPath($document);
foreach($xpath->query('//everyone/guest') as $guestNode) {
    $xml .= $document->saveXML($guestNode);
}
person BlackAura    schedule 15.12.2009
comment
Это сработало, но по какой-то причине я продолжал добавлять дополнительное пространство к вещам. Думаю, я мог бы удалить его с помощью функции trim(). Спасибо за совет. - person Lothar; 15.12.2009

$reader = new XMLReader();
$reader->xml($xml_str);
$reader->read();
$inner = $reader->readInnerXML();

// $inner is your desired xml string.

Одним из преимуществ использования XMLReader является то, что он использует меньше памяти, чем SimpleXML или классы DOM. Другое дело, что это очень быстро.

person GZipp    schedule 15.12.2009
comment
Я думал, что это также будет самым быстрым, но когда я сравнил его с другими решениями, оно оказалось самым медленным. При использовании XML-файла с тысячей узлов, которые нужно было выбрать, другие решения, как правило, выполнялись примерно на 60% дольше (это решение simplexmlelement xpath в среднем занимало 5,8 мс, а это решение на основе XMLReader - 10 мс). Возможно, я сделал что-то не так. Но спасибо за совет. Помогли мне лучше понять все это. - person Lothar; 15.12.2009
comment
Я только что проверил это сам на очень большом файле, и вы правы; он медленнее, чем SimpleXML и DOMXPath, и примерно в том же соотношении, что и ваши тесты. Это меня также удивляет, поскольку я обнаружил, что в целом быстрее извлечение всех данных, узел за узлом, из больших файлов. - person GZipp; 16.12.2009
comment
Он по-прежнему использует меньше памяти? - person shredding; 13.02.2014

См. листинг 5 здесь:

person Andrey    schedule 21.09.2013

person    schedule
comment
Это было легко сделать и было так же быстро или даже быстрее, чем другие решения. Я ценю помощь. - person Lothar; 15.12.2009