0

I have issue with how to get element xml using xpath php, i already create a php file to extract the "attributes" xml by using xpath php.

What i want is how to extract every element in xml by using xpath.

test.xml

<?xml version="1.0" encoding="UTF-8"?>
<InvoicingData>
 <CreationDate> 2014-02-02 </CreationDate>
 <OrderNumber> XXXX123 </OrderNumber>
 <InvoiceDetails>
   <InvoiceDetail>
   <SalesCode> XX1A </SalesCode>
   <SalesName> JohnDoe </SalesName>
</InvoiceDetail>
</InvoiceDetails>
</InvoicingData>

read.php

<?php
$doc = new DOMDocument();
$doc->loadXML(file_get_contents("test.xml"));
$xpath = new DOMXpath($doc);
$nodes = $xpath->query('//*');
$names = array();
foreach ($nodes as $node)
{
    $names[] = $node->nodeName;
}
echo join(PHP_EOL, ($names));
?>

From the code above it will print like this :

CreationDate OrderNumber InvoiceDetails InvoiceDetail SalesCode SalesName

So, the problem is, how to get the element inside the attribute, basically this is what i want to print :

2014-02-02 XXXX123 XX1A JohnDoe

1 Answer 1

1

You use $node->textContent to get the textual value of the node (and its descendants, if any).


In response to your first comment:

You didn't use $node->textContent. Try this:

$doc = new DOMDocument();
$doc->loadXML(file_get_contents("test.xml"));
$xpath = new DOMXpath($doc);
$nodes = $xpath->query('//*');
$names = array();
$values = array(); // created a separate array for the values
foreach ($nodes as $node)
{
  $names[]  = $node->nodeName;
  $values[] = $node->textContent; // push to $values array
}
echo join(PHP_EOL, ($values));

However, if you only want to push the textual values when they're a direct child of an element and still want to collect all node names as well, you could do something like:

foreach ($nodes as $node)
{
  $names[] = $node->nodeName;
  // check that this node only contains one text node
  if( $node->childNodes->length == 1 && $node->firstChild instanceof DOMText ) {
    $values[] = $node->textContent;
  }
}
echo join(PHP_EOL, ($values));

And if you only care about the nodes that directly contain textual values, you could do something like this:

// this XPath query only selects those nodes that directly contain non-whitespace text
$nodes = $xpath->query('//*[./text()[normalize-space()]]');
$values = array();
foreach ($nodes as $node)
{
  // add nodeName as key
  // (only works reliable of there's never a duplicate nodeName in your XML)
  // and add textContent as value
  $values[ $node->nodeName ] = trim( $node->textContent );
}

var_dump( $values );
Sign up to request clarification or add additional context in comments.

1 Comment

thx u mate, but it not print anything, here the updated code foreach ($nodes as $node) { $names[] = $node->nodeName; } echo join(PHP_EOL, ($names));

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.