Be Lazy - use XPATH to search for element in xml

I worked in application that the input to the application was XML files that was placed in a specific folder.
The XML file represent an order. The application load the XML file from this directory and process the order. The application process the order only if the order was valid . Validation was done by checking some fields like sequence, process date ...
The QA or the developer that debug the application create a new input to the application by taking old XML ,open it in notepad ,look for these fields and fixed them (like increment the sequence) in order to create new valid XML. In some cases that system failed to generated valid XML i saw developers open big XML in notepad and by CTRL+F look item by item to check which item has invalid description.

To all hard workers developers i am saying - Be Lazy do it by XPATH.

Like all other "Be lazy" cases there is a small learning curve but after you got used to it you will see how XPATH is saving time. Keep your favorite XPATH tricks and expression in your knowledge management tool, so in O(1) you will find your favorite XPATH.

The following link is the best single link that i know (you are welcome to share your favorite one). You will find there a simple table with lots of practical XPATH examples.

*Partial snapshot of the XPATH table.

Here are some additional ones:
//Seq[Property/@InternalName="GroupId" and Property="20"]

//PersonList[count(Person)=0] - Empty PersonList with no Person node

count(//PersonList[count(Person)=0])

//title[not(text())] - titles with no content

//title[not(node())] - titles with no child

../ - One level up

//item[ name( following-sibling::*[1] ) != 'description' ]- This XPath matches ALL which are not followed by directly.

The great part that you don't need to open these XML any more and you can do all through PowerShell. 

Some examples:


$xml = ' title="foo"/>'
$xml | Select-Xml '//book'
Node    Path          Pattern
----    ----          -------
book    InputStream   //book

Remove Nodes:
PS> $xml =[xml]' title="foo"/> title="bar"/>'
PS> $xml | Select-Xml -XPath '//book' | 
        Foreach {$_.Node.ParentNode.RemoveChild($_.Node)}
See more at.

Select-Xml '//User[contains(Friends/Friend/@Name, "Bar")]' $xml |%{$_.Node.Name}
With namespace:
$ns = @{ e = "http://avaya.com/OneXAgent/Settings" }
$xml = (gc lotusnotes.xml) 
Select-Xml -Xml $xml -XPath "/e:Settings/e:Directory/e:DirectorySetting/@name" -Namespace $ns | select -expand Node | select -expand '#text'
You can also search for all XML in a specific path or you can take advantage of poweshell pipeline and send a list of XML as input like this:
Get-ChildItem . -r -file | Select-Xml -XPath "//node[a='1']"
You can also use linq and all .Net XML features.

So be lazy - use XPATH!

אין תגובות:

הוסף רשומת תגובה