Home > front end >  XML "Identifying" Tag
XML "Identifying" Tag

Time:11-09

I have an XML File where root elements have a nested tag to identify the node. How could I grab the node by the specific tag contained within the root element?

Below I have tag named "master", which can contain "old" or "new" value. How could I grab just "new"?

Sample File:

<xml>
    <foo>
        <master>New</master>
        <data>
            <val1>Value</val1>
        </data>
    </foo>
    <foo>
        <master>Old</master>
        <data>
            <val1>Value</val1>
        </data>
    </foo>
</xml>

Select-XML does not work because sometimes the file has tags the are not closed.

With this code, I can get val1 from both nodes

[xml] $xml = Get-Content "$file"

$xml.xml.foo.data

I tried

$xml.xml.foo.data.val1 | Where-Object ($xml.xml.foo.master -eq "New")

and I tried

if ($xml.xml.foo.master -eq "New") {$xml.xml.foo.data.val1}

Sorry if my xml terminology doesn't make sense.

CodePudding user response:

To be clear: if the input XML isn't well-formed (syntactically valid XML), no XML-parsing solution will work - whether via a [xml] cast or via Select-Xml.

If your XML is well-formed:

Via [xml] and PowerShell's adaption of the XML DOM:

$xml.xml.foo.Where({ $_.master -eq 'New' }, 'First')

If you want to find multiple master elements with text content New, remove the 'First' argument.


Via Select-Xml (pipe to Select-Object -First 1 to limit to one match), if the XML is also valid (well-formed and conforms to referenced schemas - n/a to the sample XML):

(Select-Xml -XPath '/xml/foo[master="New"]' -LiteralPath file.xml).Node

As for using Get-Content with an [xml] cast to parse an XML file:

  • Use -Raw with Get-Content to speed it up.

  • Beware of potentially misreading the XML file - see the bottom section of this answer.

  • Related