Check if node exists using XSLT

To begin with, I would like to ask if there is a difference between the following two operators for XML nodes:

  • check if the node is an empty node;
  • check if node exists;

Suppose I have an XML file:

<claim_export_xml> <claim_export_xml_row> <claim_number>37423</claim_number> <total_submitted_charges>0</total_submitted_charges> <patient_control_no/> <current_onset_date>2009-06-07 00:00:00</current_onset_date> 

and I want to check if the "current_onset_date" node exists, I used the following XSLT:

 <xsl:for-each select="claim_export_xml_row "> <xsl:if test="claim_number =$mother_claim_no and /current_onset_date "> 

For each cycle, there is some logic that I have to deal with in order for the cycle to work. But after starting this XSLT, I got the wrong result, the XML data will not be captured by my XSLT. But I donโ€™t think that using current_onset_date = '' "is also correct, as it checks if current_onset_date does not contain anything.

Can someone tell me where my mistake is and also help me with my question at the beginning, thanks!

+6
xml xslt
source share
2 answers

It should work, except that you have two "and", and you do not need leading / before current_onset_date.

If you want to check for emptiness, you can use:

 <xsl:for-each select="claim_export_xml_row "> <xsl:if test="claim_number =$mother_claim_no and current_onset_date != ''"> 

The reason for this is that the string value of an element is a concatenation of all the text inside it, so this expression will only select strings where current_onset_date exists and contains a non-empty string. If you want to exclude elements that contain nothing but spaces, you can write:

 <xsl:for-each select="claim_export_xml_row "> <xsl:if test="claim_number =$mother_claim_no and normalize-space( current_onset_date ) != ''"> 
+4
source share

I would like to ask if there is a difference between the following two for XML nodes:

1. Check if the node is an empty node;

2. check if node exists;

This requires different expressions to verify : a node that does not exist is not an empty node:

 current_onset_date 

this selects all current_onset_date children of the current node. Its boolean value is true() if and only if at least one such child exists, and false() otherwise.

 current_onset_date/text() 

this selects any text node children of any current_onset_date children of the current node. If there are none, its boolean value is false() ; otherwise, true() ,

Even if an element does not have text nodes as children, it can still have a non-empty string value, because it can have elements as descendants, and some of these element children can have text node data.

 current_onset_date[not(string(.))] 

this selects all the current_onset_date children of the current node that have an empty string ('') as their string value. This may work well for an "empty element."

If by blank you mean an element whose string value is either empty or just whitespace, then this expression:

 current_onset_date[not(normalize-space())] 

this selects all the current_onset_date children of the current node that have an empty string (``) or a string with a space only as their string value.

Can someone tell me where my mistake is

In your code:

 <xsl:for-each select="claim_export_xml_row "> <xsl:if test="claim_number =$mother_claim_no and /current_onset_date "> 

the expression in the test attribute is always false() , because /current_onset_date means: the top element (of the document) with the name "current_onset_date", but the top element in your case is named claim_export_xml

You probably want :

 claim_number =$mother_claim_no and current_onset_date 

And if you want the element to be "non-empty" then:

  claim_number =$mother_claim_no and current_onset_date[normalize-space()] 
+17
source share

All Articles