Home > Back-end >  Accessing XML data using Xpath and GetElementbyID
Accessing XML data using Xpath and GetElementbyID

Time:08-28

I am new powershell and not very good at it. Please be patient if I am using the wrong words.

Lets say the content of my.Xml file is:

<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.3.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
    <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
    <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
    <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
    <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
    <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
    <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
    <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
    <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
]>
<svg version="1.1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
     xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 500 500"
     style="enable-background:new 0 0 500 500;" xml:space="preserve">
<switch>
    <foreignObject requiredExtensions="&ns_ai;" x="0" y="0" width="1" height="1">
        <i:aipgfRef  xlink:href="#adobe_illustrator_pgf">
        </i:aipgfRef>
    </foreignObject>
    <g i:extraneous="self">
        <g id="Background">
            <rect style="fill:#FFFFFF;stroke:#000000;stroke-miterlimit:10;" width="500" height="500"/>
        </g>
        <g id="Guides" style="display:none;">
            <rect y="400.25" style="display:inline;fill:none;" width="500" height="149.75"/>
        </g>
        <g id="Card_Symbl">
            <g id="Layer_10">
                <polygon style="fill:#E30613;" points="436.87,87.48 31.42,175.37 192.19,246.84 214.13,403.67                "/>
            </g>
        </g>
        <g id="Card_Modifier">
            <rect y="424" style="fill:#009FE3;" width="500" height="76"/>
        </g>
        <g id="Card_Short_Name">
            <text transform="matrix(1 0 0 1 32.4003 480.7129)" style="fill:#FFFFFF; font-family:'MyriadPro-Regular'; font-size:70px;">Hello, World</text>
        </g>
        <g id="Card_HUD">
            <g id="Bottom_Right">
                <rect x="408" y="348" width="92" height="76"/>
                <text transform="matrix(1 0 0 1 420.9258 411)" style="fill:#FFED00; font-family:'MyriadPro-Regular'; font-size:75px;">-</text>
            </g>
            <g id="Bottom_Left_00000030455522749116218520000014918866582792132275_">
                <rect y="348" width="88" height="76"/>
                <text transform="matrix(1 0 0 1 5 411)" style="fill:#FFED00; font-family:'MyriadPro-Regular'; font-size:75px;">1</text>
            </g>
            <g id="Top_Right">
                <rect x="408" width="92" height="76"/>
                <text transform="matrix(1 0 0 1 421 60)" style="fill:#FFED00; font-family:'MyriadPro-Regular'; font-size:75px;">-</text>
            </g>
            <g id="Top_Left">
                <rect style="fill:#008D36;" width="92" height="76"/>
                <text transform="matrix(1 0 0 1 12 60)" style="fill:#FFED00; font-family:'MyriadPro-Regular'; font-size:75px;">-</text>
            </g>
        </g>
    </g>
</switch>
</svg>

The file is imported like this:

$xmlSample = Get-Content -Raw -Path ".\FlashCard V4.svg"
$XML = [xml]$xmlSample

I am trying to navigate its structure. I have tried:

$xml.GetElementById(Card_Symbl)

Powershell returns nothing. I then tried :

$var = Select-Xml -Xml $XML -XPath "/svg/switch"

Again, Powershell returns nothing.

I managed to figure this out:

$xml.svg.Switch.g.g.g

It works as expected, Powershell returns all the data at that "level" but I dont see this being that versatile though. In a medium to large data set, this would be daunting.

Reading from the docs and this book I am learning from, I really like the Select-Xml -Xml $XML -XPath "/svg/switch" method. it makes things as simple as navigating a directory or a folder in file explorer.

If I can ask, can I see one working example of :

$xml.GetElementById(Card_Symbl)

And one working example of:

$var = Select-Xml -Xml $XML -XPath "/svg/switch"

Where both cases use my above xml sample and will return some the data that is targeted.

I'm open to suggestion as long as they are in Powershell.

CodePudding user response:

That document has a default namespace, so you must namespace-qualify your node references, eg

Select-Xml -Xml $XML -XPath "/s:svg/s:switch" -Namespace @{s = "http://www.w3.org/2000/svg"}

To retrieve "Hello, World" you would use an XPath like this:

$e = Select-Xml -Xml $XML -XPath '/s:svg/s:switch/s:g/s:g[@id="Card_Short_Name"]/s:text/text()' -Namespace @{s = "http://www.w3.org/2000/svg"}
$e.Node.Value

The key bit is this expression

s:g[@id="Card_Short_Name"]

Which finds s:g elements with an id attribute of "Card_Short_Name".

The other thing to note is that XmlElement doesn't have a .Value, you have to grab the text node under the element to extract the value with s:text/text().

  • Related