Al Phaba
Al Phaba

Reputation: 6755

How to query xpath with powershell with namespace

I have a xml with namespaces, now I do not know how to use the Select-XML cmdlet to evaluate a xpath string. Concrete I want to retrieve the value of the formfield with the key foobar.

So my xpath query is

 /ns3:penrequest/formfields/field[@key='foobar']/@value

In my Powershell-Script I try to use this

Select-XML -path $filename -xpath "/ns3:penrequest/formfields/field[@key='foobar']/@value"

This results in the following error

Select-Xml : Namespace-Manager oder 'XsltContext' erforderlich. Diese Abfrage hat einen Präfix, eine Variable oder eine
benutzerdefinierte Funktion.
In Zeile:1 Zeichen:1
+ Select-Xml -Path .\datapath\sample.xml -XPath "/ns3:penrequest/formfi ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Select-Xml], XPathException
    + FullyQualifiedErrorId : System.Xml.XPath.XPathException,Microsoft.PowerShell.Commands.SelectXmlCommand

How do I define the namespace here?

This is my sample-xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns3:penrequest xmlns:ns2="urn:srs.pdx.metadata" 
    xmlns:ns3="urn:de.srs.pen.virtual.request" 
    xmlns:ns4="urn:srs.pdx.servicelist" 
    xmlns:ns5="urn:srs.pdx.metaxaconfig" 
    xmlns:ns6="http://verification.ws.pen.srs.de/" formid="QS_MFFM_Reinigung_18_50_1_1" instanceid=".2000000031896" pduser="SYSTEM/system" penid="SRS-000-EE0-3Q" start="2019-09-17T14:10:33.620+02:00" stop="2019-09-09T12:00:47.439+02:00" transmission="2019-09-30T15:37:15.050+02:00" creator="MFFM/test_ma" pageid="" patternid="" updates="6" clientid="PDiX API V5.0.5-SNAPSHOT0" lastupdate="2019-09-17T12:38:29.677Z">
    <sessions>
        <session order="1" created="2019-09-17T12:10:33.620Z" finished="2019-09-17T12:10:33.620Z" sourcetype="VP" firstProcessed="2019-09-17T12:10:33.620Z" lastProcessed="2019-09-17T12:10:33.620Z" extended="0" device="TBS-000-MFF-02" datahash="5db0c36f4378d308394b75b3c5990cad2bc87402" user="MFFM/test_ma" lastupdate="2019-09-17T12:10:33.637Z"/>
    </sessions>
    <formfields>
        <field group="" key="foobar" fullname="foobar" value="35000013" start="2019-09-17T14:10:33.620+02:00" stop="2019-09-17T14:10:33.620+02:00" sourcetype="VP" fieldtype="EF" icrconfidence="100000" icrrecognition="100000" pageid="" device="TBS-000-MFF-02" sessionid="1" updateid="1" user="MFFM/test_ma" lastupdate="2019-09-17T12:10:34.233Z">
            <details>
                <detail session="1" value="35000013" start="2019-09-17T14:10:33.620+02:00" end="2019-09-17T14:10:33.620+02:00" user="MFFM/test_ma" lastupdate="2019-09-17T12:10:34.233Z"/>
            </details>
            <attributes/>
        </field>
        <field group="" key="someOtherText" fullname="someOtherText" value="sample" start="2019-09-17T14:10:33.620+02:00" stop="2019-09-17T14:10:33.620+02:00" sourcetype="VP" fieldtype="EF" icrconfidence="100000" icrrecognition="100000" pageid="" device="TBS-000-MFF-02" sessionid="1" updateid="1" user="MFFM/test_ma" lastupdate="2019-09-17T12:10:34.250Z">
            <details>
                <detail session="1" value="sample" start="2019-09-17T14:10:33.620+02:00" end="2019-09-17T14:10:33.620+02:00" user="MFFM/test_ma" lastupdate="2019-09-17T12:10:34.250Z"/>
            </details>
            <attributes/>
        </field>

    </formfields>
    <attributes>
        <attribute module="foo" name="state" value="OK" device="1" user="test" lastupdate="2019-09-17T12:38:29.643Z"/>
    </attributes>
</ns3:penrequest>

Upvotes: 2

Views: 1433

Answers (2)

mklement0
mklement0

Reputation: 437042

A pragmatic solution based on avoiding namespace headaches is to use PowerShell's dot notation, which ignores namespaces:

[xml] $xmlDoc = Get-Content -Raw $filename
$xmlDoc.penrequest.formfields.field.Where({ $_.key -eq 'foobar' }).value

Using namespaces with Select-Xml is a bit more cumbersome:

# Wrap in (...).Node.Value to extract the matched attribute's *text*.
Select-Xml -Path $filename `
  -NameSpace @{ ns3 = 'urn:de.srs.pen.virtual.request' } `
  -XPath "/ns3:penrequest/formfields/field[@key='foobar']/@value"

Note how parameter -NameSpace requires a hashtable (@{ ... }) that maps the URIs for all the namespace-qualified elements used in the XPath query.


For more information, see this answer to a related question.

Upvotes: 2

Ed Bangga
Ed Bangga

Reputation: 13006

use local-name() to ignore namespace

/*[local-name()='penrequest']/formfields/field[@key='foobar']/@value

Upvotes: 0

Related Questions