Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a xpath to match all elements except a particular element

Tags:

I am writing an XSL transformation. I want to write a template which matches all the child elements of the document except one particular node. My xml looks like this -

<Document>     <NodeA></NodeA>      <NodeB></NodeB>      <ServiceNode></ServiceNode>      <NodeX></NodeX> </Document> 

I want to write a template that matches all nodes except ServiceNode i.e. NodeA to NodeX. How to write this Xpath to get -

<xsl:template match="ALL Nodex Except ServiceNode"> 
like image 416
Unmesh Kondolikar Avatar asked Feb 01 '11 07:02

Unmesh Kondolikar


People also ask

What is XPath expression to select all the book elements?

/bookstore/book[price>35.00] Selects all the book elements of the bookstore element that have a price element with a value greater than 35.00. /bookstore/book[price>35.00]/title. Selects all the title elements of the book elements of the bookstore element that have a price element with a value greater than 35.00.

What is the * indicates in XPath?

By adding '//*' in XPath you would be selecting all the element nodes from the entire document. In case of the Gmail Password fields, .//*[@id='Passwd'] would select all the element nodes descending from the current node for which @id-attribute-value is equal to 'Passwd'.

Is XPath unique for each element?

Unlike ID attributes, every element in a web page has a unique XPath.

Can we use and with Contains in XPath?

Using XPath- contains() method, we can write the Java code along with the dynamic XPath location as: findElement(By. xpath(“//*[contains(@id,'lst-ib')]”)); Using the 'contains' function, we can extract a list of web elements containing the matching text throughout the web page.


2 Answers

I want to write a template that matches all nodes except ServiceNode i.e. NodeA to NodeX.

If by "node" you mean element, then use:

<xsl:template match="*[not(self::ServiceNode)]"> 

If by "node" you mean any node (of type element, text, comment, processing-instruction): use

<xsl:template match="node()[not(self::ServiceNode)]"> 

If you want only children of Document to be matched use:

<xsl:template match="Document/node()[not(self::ServiceNode)]"> 

If you want only children of the top element to be matched use:

<xsl:template match="/*/node()[not(self::ServiceNode)]"> 
like image 183
Dimitre Novatchev Avatar answered Sep 28 '22 05:09

Dimitre Novatchev


You should better use this expression:

*[not(self::ServiceNode)] 

As incorporated in an XSLT:

<xsl:stylesheet     version="1.0"     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">     <xsl:output method="text"/>      <xsl:template match="/*">         <xsl:apply-templates select="*[not(self::ServiceNode)]"/>     </xsl:template>      <xsl:template match="*">         <xsl:value-of select="."/>         <xsl:text>&#xA;</xsl:text>     </xsl:template>  </xsl:stylesheet> 

With this XML sample:

<Document>     <NodeA>1</NodeA>     <NodeB>2</NodeB>     <ServiceNode>3</ServiceNode>     <NodeX>4</NodeX> </Document> 

It will give a correct result:

1 2 4 
like image 32
Flack Avatar answered Sep 28 '22 05:09

Flack