Reputation: 33
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.
Upvotes: 2
Views: 292
Reputation: 34421
Using PowerShell with xml linq
using assembly System
using assembly System.Xml.Linq
$Filename = "c:\temp\test.xml"
$xDoc = [System.Xml.Linq.XDocument]::Load($Filename)
$root = [System.Xml.Linq.XElement]$xDoc.Root
$ns = [System.Xml.Linq.XNamespace]$root.GetDefaultNamespace()
$gs = $xDoc.Descendants($ns + "g")
$cardSymbol = [System.Linq.Enumerable]::Where($gs, [Func[object,bool]]{ param($x) [string]$x.Attribute("id").Value -eq "Card_Symbl"})
Write-Host "cardSymbol = " $cardSymbol
Upvotes: 0
Reputation: 88852
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()
.
Upvotes: 2