Я должен признать, что это было не так просто, как можно было бы подумать. Вот что я придумал:
$xml = new DOMDocument;
$xml->load('doc.xml');
// find just the <b> node(s)
$xpath = new DOMXPath($xml);
$results = $xpath->query('/a/b');
// get entire <b> node as text
$node = $results->item(0);
$text = $xml->saveXML($node);
// remove encapsulating <b></b> tags
$text = preg_replace('#^<b>#', '', $text);
$text = preg_replace('#</b>$#', '', $text);
echo $text;
Относительно запроса XPath
Запрос возвращает все совпадающие узлы, поэтому, если имеется несколько совпадающих тегов <b>
, вы можете просмотреть $results
, чтобы получить их все.
Мой запрос для '/a/b'
предполагает, что <a>
является корнем, а <b>
является его дочерним / непосредственным потомком. Вы можете изменить его для разных сценариев. Вот ссылка на XPath . Некоторые корректировки могут включать в себя:
'a/b'
–– <b>
является потомком <a>
, но <a>
где угодно, а не только в корне
'a//b'
–– <b>
является потомком <a>
независимо от его глубины, а не просто прямым ребенком
'//b'
–– все <b>
узлов в любом месте документа
Относительно способа получения содержимого строки
Я пытался использовать $node->nodeValue
или $node->textContent
, но оба они удаляют теги <c>
и <d>
, оставляя только текстовое содержимое этих тегов. Я также пытался привести его как объект DOMText, но это не сработало напрямую и принесло больше хлопот, чем оно того стоило.
Относительно использования регулярных выражений
Это можно было бы сделать без регулярных выражений, но мне было проще всего их использовать. Я хотел убедиться, что я удалил <b>
и </b>
только в самом начале и конце строки, на случай, если в содержимом будут другие узлы <b>
.