Reputation: 6755
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
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
Reputation: 13006
use local-name()
to ignore namespace
/*[local-name()='penrequest']/formfields/field[@key='foobar']/@value
Upvotes: 0