Frage

I have this as a part of my XML that I am loading in a DOM Document:

<error n='\Author'/>
Some Text 1 
<formula type='inline'><math xmlns='http://www.w3.org/1998/Math/MathML'><msup><mrow/> <mrow><mn>1</mn><mo>,</mo></mrow> </msup></math></formula>
Some Text 2 
<formula type='inline'><math xmlns='http://www.w3.org/1998/Math/MathML'><msup><mrow/> <mn>2</mn> </msup></math></formula>

<error n='\address' />

My goal is to get everything as nodeValue between the

<error n='\Author' />

And

<error n='\address' />

How can this be done?

I tested this:

$author_node = $xpath_xml->query("//error[@n='\Author']/following-sibling::*[1]")->item(0);
if ($author_node != null) {

    $i              = 1;
    $nextNodeName   = "";
    $author     = "";


    while ($nextNodeName != "error" && $i < 20) {
        $nextNodeName = $xpath_xml->query("//error[@n='\Author']/following-sibling::*[$i]")->item(0)->tagName;

        if ($nextNodeName == "error")
            continue;

        $author .= $nextNode->nodeValue;
    }

But Am getting only the formula content, not the text between formulas. Thank you.

War es hilfreich?

Lösung

The *only selects element nodes, not text nodes. So only the <formula> elements are selected. You need to use node(). But you could use xpath directly to selected the needed nodes. Look for an explanation of the Kayessian method.

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);

$nodes = $xpath->evaluate(
  '//error[@n="\\Author"][1]
    /following-sibling::node()
      [
        count(
          .|
          //error[@n="\\Author"][1]
            /following-sibling::error[@n="\\address"][1]
              /preceding-sibling::node()
        )
        =
        count(
          //error[@n="\\Author"][1]
            /following-sibling::error[@n="\\address"][1]
              /preceding-sibling::node()
        )
      ]'
);

$result = '';
foreach ($nodes as $node) {
  $result .= $node->nodeValue;
}
var_dump($result);

Demo: https://eval.in/125494

If you want to save not only the text content, but the XML fragment, you can use DOMDocument::saveXml() with the node as argument.

$result = '';
foreach ($nodes as $node) {
  $result .= $node->ownerDocument->saveXml($node);
}
var_dump($result);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top