4

I have an xml:

<Customer id="">
 <Name />
 <Address />
</Customer>

I would like to select ONLY a root node with its attributes without its child nodes:

<Customer id=""/ >

Is such thing possible with XPath?

Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
Timofey
  • 2,478
  • 3
  • 37
  • 53

4 Answers4

2

No, this is not possible in XPath.

You can't select the node without its children, because without its children it would be a different node, hence you would not be selecting a node from the original document.

To create the output you want you need to use a language which allows you to create new nodes, so you can't do it in XPath. You can use XQuery to create new nodes, this should work:

element {fn:node-name(/*)} {/*/@*}
Nick Jones
  • 6,413
  • 2
  • 18
  • 18
2

XPath does not alter any source XML document and this is by design.

To produce a new XML document from an existing one, transformation is needed.

XSLT has been especially designed for transforming a set of trees (including XML documents) into result trees.

This transformation:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>

    <xsl:template match="/*">
      <xsl:copy>
       <xsl:copy-of select="@*"/>
      </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

when applied on the provided XML document:

<Customer id="">
    <Name />
    <Address />
</Customer>

produces the wanted, correct result:

<Customer id=""/>
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
0
$doc = new DOMDocument();
$doc->loadHTML($str);

$xPath = new DOMXpath($doc);
$xPathQuery = "//text()[contains(translate(.,'abcdefghijklmnopqrstuvwxyz',  'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), '<Customer id=\"\">')]";
$elements = $xPath->query($xPathQuery);

if($elements->length > 0){

foreach($elements as $element){
    print "Found: " .$element->nodeValue."<br />";
}
  • Thanx for an answer, but I need XPath construct, since I do the stuff in T-SQL. Something like: select @XmlData.query('/[nochildrenhere]') – Timofey Sep 14 '10 at 10:27
  • Aah ok, then i can't help you, sorry! –  Sep 14 '10 at 10:30
0

This XQuery expression:

element {name(/*)} {/*/@*}

Output:

<?xml version="1.0" encoding="UTF-8"?><Customer id=""/>