3

New to Xpath, intermediate with powershell. Spent a good amount of time researching yesterday, I could not find a single example of xpath sum() or count() expressions within a powershell -XPath command. I'm writing this verbosely as my first stackoverflow question so that future people can find this article for a clear example answer from an XPert.

Objectives (2): 1. Count() the critical processes. 2. SUM() the transactions processed by critical processes.
Note: The output of the powershell XPath command should be the raw number.

<units>
<unit>
  <unitName>Generic Process Unit</unitName>
    <attribute>
      <name>Process Type</name>
      <value>Critical Process</value>
    </attribute>
    <attribute>
      <name>Transactions Processed</name>
      <value>10</value>
    </attribute>
</unit>

<unit>
  <unitName>Generic Process Unit</unitName>
    <attribute>
      <name>Process Type</name>
      <value>Trivial Process</value>
    </attribute>
    <attribute>
      <name>Transactions Processed</name>
      <value>7</value>
    </attribute>
</unit>

<unit>
  <unitName>Generic Process Unit</unitName>
    <attribute>
      <name>Process Type</name>
      <value>Critical Process</value>
    </attribute>
    <attribute>
      <name>Transactions Processed</name>
      <value>5</value>
    </attribute>
</unit>
</units>

My Best attempt at the SUM function. Didn't even try the Count:

select-xml -path mine.xml -XPath '//attribute[value="Critical Process"]/../attribute[name="Transactions Processed"][sum(value)]' | Select-Object -ExpandProperty node | select Value

Edit: Working XPath from notepad++ XMLTool plugin is below, but still need the Powershell equivalent (this doesn't work in Powershell):

sum(//attribute[value="Critical Process"]/../attribute[name="Transactions Processed"]/value)

Errata: The reason it needs to be XPath only expressions, is that I'm only using powershell to construct and validate my XPath strings. The end goal is to put those strings into a non-powershell software that will actually use the XPath string. That software gives me no way to validate an XPath, and it takes 20 minutes to tell if it works after I put it in, so I'm using powershell as my testbed.

I've changed the item names, descriptions, and removed attributes to make the example simpler. However, I don't know if the "schema" words are important, so here is an example of an original "value" line.

<value xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xs="http://www.w3.org/2001/XMLSchema" xsi:type="xs:string">Critical Process</value>

Issues:

  • It seems that a given XPath expression needs to be tweaked just a bit to work in powershell. For example, after -XPath '/xpath/node' you seem to always need to end with: '/text()' | Select-Object -ExpandProperty node | select Value to actually see the output you want.

  • Microsoft has XPath documentation, and Powershell documentation, but no "XPath Expressions in Powershell" documentation.

  • Most internet examples of expressions use "Powershell + XPath" do bare minimum XPath to get data object out, and then loop through using foreach in powershell.

  • It looks like the command syntax might have some dependency on XPath versions 1, 2, etc.

Thanks in advance.

2 Answers 2

3

As far as I can tell those functions won't work with Select-Xml as it appears to use [XmlDocument]::SelectNodes behind the scenes which can only return nodes.

As an alternative you can use a navigator:

$xml = @'
#your xml here
'@ -as [xml]

$xml.CreateNavigator().Evaluate('count(//unit)')
$xml.CreateNavigator().Evaluate('sum(//unit)')
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the feedback Andy. I think your suggestion that my goal might simply be impossible due to the design of select-xml is probably the answer to my question. I'll definitely accept it if we can confirm. I'll start looking for an official document. As for your alternative, it will not work for my situation. Thanks again.
@JerryW. You can decompile the cmdlet to see the code its running behind the scene. Why can't you use a "native" XmlDocument object?
The reason it needs to be XPath only expressions, is that I'm only using powershell to construct and validate my XPath strings. The end goal is to put those strings into a non-powershell software that will actually use the XPath string. That software gives me no way to validate an XPath, and it takes 20 minutes to tell if it works after I put it in, so I'm using powershell as my testbed.
0

The counting should be as simple as

count(/units/unit[attribute[name="Process Type"][value="Critical Process"]])

(using two nested levels of predicates to ensure that the name and value are both on the same attribute). For the sum, we just add a bit to the end of the expression

sum(/units/unit[attribute[name="Process Type"][value="Critical Process"]]/attribute[name="Transactions Processed"]/value)

But note that both of these expressions will return a numeric value, not a node set, which may be what is confusing powershell.

1 Comment

Thanks Ian, indeed your statements both are functional XPath commands. Unfortunately, since they do not work in powershell, I think they lend support to Andy's theory that select-xml in powershell is only designed to return nodes and node sets. I wonder if there's an alternative powershell / xpath module that can return numbers.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.