Reputation: 13
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
Upvotes: 0
Views: 112
Reputation: 22783
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 );
Upvotes: 1