Changing text inside and existing XML file

I have an xml file which makes reference to several other files listed one after the other in order. The files listed have some basic metadata listed for each of these files respectively. The metadata includes such entries as File Size, MD5 hash, and File Type.

Can someone provide me with some sample code that shows how to go in and change these metadata values?

Specifically I can Generate a new MD5 Hash and I can determine file size with Powershell scripting but then how do I take that MD5 hash and File Size result and use them to replace old existing MD5, File Size, and File Type information listed for multiple file listings within the XML document?

I was thinking of something like assigning a variable to each on of the results that were generated by PowerShell but then I still have no way to reference those variables to the various files and their respective metadata uniquely, that will be listed in the XML document. I need to be able to perform all of the above-mentioned automatically.

Please answer ASAP.

Thank you

Didn’t the last thread in below post help ?

https://powershell.org/forums/topic/return-keystroke-in-powershell/

Last thread is VERY HELPFUL for changing text in one node. i.e. <size>“Data Needing to be Changed”</size>.

But what if that same XML file has multiple nodes with the same name? How can you tell PowerShell which node to apply the change to?

i.e. <size>“Data Needing to be Changed”</size>

further down in the script another instance of same thing:
<size>“Data Needing to be Changed”</size>

further down in the script same thing… and so on.

How can powershell tell the difference so it knows which Node to place the data into?

Will give some tips.

Search for Using Xpaths in PowerShell. XML stuffs via PowerShell is a vast thing. But this will help you to get started.

ok thank you

For Xpaths in PowerShell research I can find many examples and uses for this tool for a specific NODE. Doesn’t seem to work when you have multiple nodes with the same name within one XML document.

Also the above mentioned tool has a primary use of Query inside XML document, not updating data with in a Node.

Your thoughts Mr. Kvprasoon?

If the ParentNode is not the same, you can trigger off that.

Tony:

Any scripting examples you would like to share based on your initial response please?

@nal2us2 There are filters in XML, you can use it with XPath. It acts like a where condition. Better if you can share a sample XML of what you have. use gist.github.com to share XML.

Not knowing the structure of your XML, and what you ask having many different answers, as Kvprasoon has suggested, can you share what you have so far?

You state there will be many different <size> attributes. Each one of those SHOULD have a ParentNode. If that Node is different for each of the Child <size> nodes, my thought was to use the ParentNode to decide which <size> attribute to change.

$xmlData = New-Object System.XML.XMLDocument
$xmlData.PreserveWhiteSpace = $True
$xmlDoc = ‘C:\Path\To\XML\file.xml’
$xmlData.Load($xmlDoc)
$xmlSizeNodes = $xmlData.SelectNodes(‘///*/Size’)

The filter shown is an example only not knowing your XML Structure

You can then do something like:

ForEach($node in $xmlSizeNodes) {

if ($node.ParentNode.Name -Match ‘WhatEver’) {

do something

}

Writing the XML file back is pretty straightforward:

$xmlData.Save($xmlDoc)

OK Tony, here is a sample of the XML I wish to change.
Notice all the similar tag names:

<type>subtitles</type>

<eBarcode>E2135087</eBarcode>

<componentId>4732621</componentId>

<fileName>HBOMAXLAT_LIGHTS_OUT_16x9_E2056834_FEATURE_2_0_LTRT_8800521_ENGLISH_SDH.itt</fileName>

<size>80022</size>

<checksumValue>7046d57a5d9b47e66848e2ca724668cf</checksumValue>

<checksumType>md5</checksumType>

<territory/>

<language iso="EN">ENGLISH</language>

<textType>SDH</textType>

<format>ITT</format>

</subtitle>


-<subtitle>

<type>subtitles</type>

<eBarcode>E2134720</eBarcode>

<componentId>4732668</componentId>

<fileName>HBOMAXLAT_LIGHTS_OUT_16x9_E2056834_FEATURE_2_0_LTRT_8800521_PORTUGUESE_BRAZIL_FORCED.itt</fileName>

<size>4590</size>

<checksumValue>b403db2252c7be0a9e0d3c7a921eeea7</checksumValue>

<checksumType>md5</checksumType>

<territory/>

<language iso="PT_BR">PORTUGUESE_BRAZIL</language>

<textType>FORCED</textType>

<format>ITT</format>

</subtitle>


-<subtitle>

<type>subtitles</type>

<eBarcode>E2134889</eBarcode>

<componentId>4732307</componentId>

<fileName>HBOMAXLAT_LIGHTS_OUT_16x9_E2056834_FEATURE_2_0_LTRT_8800521_SPANISH_LATIN_FORCED.itt</fileName>

<size>4839</size>

<checksumValue>9b936a026a444ad18209935ee57a5039</checksumValue>

<checksumType>md5</checksumType>

<territory/>

<language iso="ES">SPANISH_LATIN</language>

<textType>FORCED</textType>

<format>ITT</format>

</subtitle>

You will notice all the similar tag names. Can you provide some sample code of how to choose which tag gets the new data that I wish to input?

XML tags can have same names, but they will be under different parents and there will be some unique value to differentiate them, in this case I can see filename is unique. If you wan to get checksum for a filename

$FileName = 'HBOMAXLAT_LIGHTS_OUT_16x9_E2056834_FEATURE_2_0_LTRT_8800521_ENGLISH_SDH.itt'
[XML]$XML - Get-Content -Path $XMLPath

$Node = $XML.SelectNode("//subtitle[@filename='$FileName']")
$Node.checksumValue # get
$Node.checksumValue.innertext = $NewValue # set
$node.Save($XMLPath)

This is the exact problem. The unique value is the data INSIDE the tags. I need to be able to differentiate one tag of the same name from another in code. The fact that one tag may be the parent tag… great! I am assuming that will be the first tag listed. The problem is the XML document will change from time to time the number of “Same Name” tags it has in it, and the data will be different every time. In the example above that I have listing three video files, the next XML sheet to be used will: 1. have a different XML name altogether, 2. Have a different number of video files and associated “Same Named” tags, AND will have different data that needs to be updated in one, some, or all of the same named tags. So again, some sample code of showing how to overcome these multiple issues in powershell would be appreciated. I was thinking of something like regex expressions, but need some sample code showing how to overcome these multiple obstacles kvprasoon, or anyone else out there who can give me something other than a “general answer”. Thank you and God bless you!!!

you can filter XML with any unique value, either the value is an attribute value(<foo attrubute-‘value’ />) or inner text (<foo>some value</foo>)

For anything changes dynamically, you can take those as user input via parameters. If you can share some code you have so far, it will be easy to understand where you are getting issue.

I have no code at this time. Only that XML example which I shared earlier.

 

Shukriya

 

You have to start putting up some code, otherwise it will be difficult for you and anyone here trying to help you out. If you have some code it will help us correcting the understanding between us.

The way your XML file is structured, you will simply have to choose what attribute you want to use as the unique value. As kvprasoon has suggested, the filename attribute is a likely one to choose and his code looks like what you need. You wont be able to use ParentNode as it is not unique in your case.