0

I have the following XML node in my XML document that I need to update:

<ImageUrl>xxx.xxx.com/imageeditor/X.jpg</ImageUrl>

With the following:

<ImageUrl>xxx.xxx.com/image/getdvimage/X/1/false/200/200/</ImageUrl>

where "X" in the first string is a number (9808 for example) and needs to be in the place of "X" in the second node. This is the only node called ImageUrl in the document, and I need to update the whole document this way. So I need help finding the X in the node and replacing it with the X in the updated node and saving the file.

I am trying this code:

[xml]$xml = Get-Content 'D:\temp\feed.xml'
Foreach ($item in (Select-XML -Xml $xml -XPath '//ImageUrl'))
{
    $oldValue = $item.node.innertext #need to get the value from the last "/" to the .jpg value 
    $newValue = [string]::Format('xxx.xxx.com/image/getdvimage/{0}/1/false/200/200/',$oldValue) #place the $oldValue into the new string here

    $item.node.Name = ???
}
$NewPath = 'D:\temp\FeedUpd.xml'
$xml.Save($NewPath)

Here is the XML I am using:

 <Product>
            <ExternalId>2127</ExternalId>
            <Name>test</Name>
                                <Description>
                <![CDATA[
               desc
                ]]></Description>
            <BrandExternalId>xxx</BrandExternalId>
            <CategoryExternalId>Foo</CategoryExternalId>
                                <ProductPageUrl><![CDATA[xxx.com/2127]]></ProductPageUrl>
                <ImageUrl>xxx.com/imageeditor/2127.jpg</ImageUrl>
            <ModelNumbers>
                <ModelNumber>2127</ModelNumber>
            </ModelNumbers>
            <ManufacturerPartNumbers>
                <ManufacturerPartNumber>2127</ManufacturerPartNumber>
            </ManufacturerPartNumbers>
            <UPCs>
                <UPC>841101002711</UPC>
            </UPCs>
        </Product>

If I could pull the Model Number to insert into the new string {0} I wouldn't have to parse the old ImageUrl, just insert the Model into the string. How would I grab the <ExternalId> and the <ImageUrl> in the loop to replace?

2
  • Foreach ($item in (Select-XML -Xml $xml -XPath '//ImageUrl')) { $item.node.Name = ??? } $NewPath = 'D:\temp\FeedUpd.xml' $xml.Save($NewPath) Running this code, it will not find the ImageUrl tag for me to even get the text from to try and do a replace. Commented Nov 16, 2017 at 18:55
  • Stepping through the code above, it doesn't step into the Foreach loop and $item never has a value Commented Nov 16, 2017 at 19:32

2 Answers 2

1

Your exact requirements for updating the <ImageUrl> elements are unclear, but here's something that demonstrates all the techniques needed (PSv4+, due the use of the .ForEach() collection operator):

$inFile = 'D:\temp\feed.xml'
$outFile = 'D:\temp\feed-updated.xml'

# Read the input file into an in-memory XML document (object model).
$xml = [xml] (Get-Content -Raw $inFile)

# Loop over all <Product> elements (anywhere in the document)
# Note: Since we already have an in-memory XML document, using method
#       .SelectNodes() is more efficient than using the Select-Xml cmdlet.
#       Similarly, the use of collection operator .ForEach() is more efficient
#       than use of the ForEach-Object cmdlet.
$xml.SelectNodes('//Product').ForEach({

  # $_ is the <Product> element at hand, and its child elements
  # can simply be accessed with *dot notation*.

  # Get the model number...
  $modelNo = $_.ModelNumbers.ModelNumber

  # ... and use it to update the <ImageUrl> child element
  $_.ImageUrl = 'xxx.xxx.com/image/getdvimage/{0}/1/false/200/200/' -f $modelNo

})

# Save the modified in-memory XML document back to disk.
# Note: 
#   * Creates a file with BOM-less UTF-8 encoding.
#   * Be sure to use an *absolute* file path, because the .NET framework's
#     current directory typically differs from PowerShell's.
$xml.Save($outFile)
Sign up to request clarification or add additional context in comments.

Comments

0

I needed this done, so I just created a console application in c# that pull in the data and parsed it quickly for me. I used the XDocument and SelectNodes to pull in the data

 XmlDocument doc = new XmlDocument();
        doc.Load(@"d:\temp\xxx.xml");
        XmlNode docElement = doc.DocumentElement;
        XmlNamespaceManager nsman = new XmlNamespaceManager(doc.NameTable);
        nsman.AddNamespace("ns", docElement.NamespaceURI);

        foreach (XmlNode row in doc.SelectNodes("//ns:Product", nsman))
        {
            string prodID = null;
            string ImageUrl = null;
            foreach (XmlNode childNode in row.ChildNodes)
            {
               //Process the node data here
            }
        }
        doc.Save(@"d:\temp\xxx.xml");

Processed my 530 rows in less than a second.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.