0

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.

arealhobo
  • 447
  • 1
  • 6
  • 17
  • "sometimes the file has tags the are not closed". Then this isn't a question about XML at all, it is a question about some other language in which tags are not always closed. – Michael Kay Nov 09 '21 at 08:21

1 Answers1

2

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.

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    So the problem is the XML is not well formed. It comes that way straight from the source. The first example does work, after I remove Illegal characters. Select-XML does not work because of the tags that are not closed, but there is no issues with this when using the xml cast. In short XML file is broken, have to use XML cast. EDIT: and Thank you! – arealhobo Nov 08 '21 at 23:38