tags:

views:

43

answers:

3

Is it possible with xpath to get the result transformed somehow, just like it can be done with SQL?

Given the following:

<a>
  <b x="1" y="2" z="3">
  <b x="2" y="2" z="3">
</a>

For example if I wanted to get all b nodes, but i don't want the z attribute to be part of the the results.

Or another thing which Iam thinking about is to receive all y nodes multiplied with a factor something like that /a/b[(@y*2)] which seems not to be possible, at least I don't know how to write it.

+2  A: 

No, with XPath, you can only select some nodes from the document. To do this, you could use XQuery (which is a superset of XPath) or XSLT.

svick
+1  A: 

With xslt you can use xsl:element to define new elements using the old ones or add attributes using xsl:attribute.

Use these to generate the elements in the way you want them from the xpath result set.

Marc van Kempen
+3  A: 

As pointed in the answer of @svick, an XPath expression can select a set of nodes from XML document(s), but it cannot alter the XML document(s) or create new document(s).

Here is an XSLT transformation that produces a new XML document in which the z attributes are omitted and the y attributes are multiplied by 2.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"&gt;
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="@z"/>

 <xsl:template match="@y">
   <xsl:attribute name="y">
     <xsl:value-of select="2* ."/>
   </xsl:attribute>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the provided XML document (corrected to be well-formed):

<a>
  <b x="1" y="2" z="3"/>
  <b x="2" y="2" z="3"/>
</a>

the wanted, correct result is produced:

<a>
   <b x="1" y="4"/>
   <b x="2" y="4"/>
</a>

The easiness and power of this solution are due to using one of the most powerful XSLT design pattern: the use of the identity rule and its overriding with specific templates only for nodes that must be processed in a specific way.

Dimitre Novatchev