Reputation: 107
I am trying to learn accessing XML files through PowerShell.
The requirement is to check through PowerShell and see if the <street>Baker street 1</street>
exist in all the three xml files.
Below are the 3 XML file and its path:
Path C:\Desktop\Path1\XML Path
1. Joe.xml
<addresses xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation='test.xsd'>
<address>
<street>Baker street 1</street>
<name>Joe Tester</name>
<age>20</age>
<university>A - UNIVERSITY</university>
</address>
</addresses>
2. Jack.xml
<addresses xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation='test.xsd'>
<address>
<name>Jack</name>
<age>19</age>
<university>B - UNIVERSITY</university>
</address>
</addresses>
3. Ryan.xml
<addresses xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation='test.xsd'>
<address>
<name>Ryan</name>
<age>23</age>
<university>C - UNIVERSITY</university>
</address>
</addresses>
If the <street>Baker street 1</street>
does not exist:
PowerShell should provide the name of the xml file where the <street>Baker street 1</street>
path is not added.
I need to update the <street>Baker street 1</street>
in the 2 xml file.
I managed to get the output for 1st scenario
Get-ChildItem -File -Path C:Desktop\Path1\XML\*.* |
ForEach-Object {
[pscustomobject] @{
HasCRLF = (Get-Content -Raw -LiteralPath $_.FullName).Contains("<street>Baker street 1</street>")
Name = $_.Name
FullName = $_.FullName
}
}
HasCRLF Name FullName
------- ---- --------
False Jack.xml C:\Desktop\Path1\XML\Jack.xml
True Joe.xml C:\Desktop\Path1\XML\Joe.xml
False Ryan.xml C:\Desktop\Path1\XML\Ryan.xml
Need your help to add the missing info to the xml file.
Upvotes: 0
Views: 920
Reputation: 61168
Iterate through the path where the xml files can be found and load each file as XmlDocument. Then the easiest would be to use the 'dot' notation to see if 'Baker street 1' can be found.
Get-ChildItem -Path 'C:\Desktop\Path1\XML' -Filter '*.xml' -File |
ForEach-Object {
# get all content as XML. Use this syntax, so you will get the encoding right
$xml = [System.XML.XMLDocument]::new()
$xml.Load($_.FullName)
[PsCustOmobject] @{
HasStreet = ($xml.addresses.address.street -eq 'Baker street 1')
Name = $_.Name
FullName = $_.FullName
}
}
Using 'dot' syntax works case-insensitive, so $xml.Addresses.Address.Street
is also fine as well as BaKeR StReEt 1
Output:
HasStreet Name FullName
--------- ---- --------
False Jack.xml D:\Test\Jack.xml
True Joe.xml D:\Test\Joe.xml
False Ryan.xml D:\Test\Ryan.xml
If you need to add the missing <street>
tag to the files that do not have it, you can do this:
Get-ChildItem -Path 'C:\Desktop\Path1\XML' -Filter '*.xml' -File |
ForEach-Object {
# get all content as XML. Use this syntax, so you will get the encoding right
$xml = [System.XML.XMLDocument]::new()
$xml.Load($_.FullName)
if (!$xml.addresses.address.street) {
Write-Host "Adding node '<street>Baker street 1</street>' to file $($_.FullName)"
$streetNode = $xml.CreateElement('street')
$streetNode.InnerText = 'Baker street 1'
[void]$xml.addresses.address.AppendChild($streetNode) # or use PrependChild() if <street> must come on top
$xml.Save($_.FullName)
}
}
Upvotes: 2