1

im trying to change the value of target to "" inside of an XML string value.

Heres what ive got so far:

New-UsingBlock (New-Object Sitecore.Data.BulkUpdateContext) {

# Get Home items
$root = Get-Item -Path "master:/sitecore/content/sitename/Content/Common/Footer"
# Get its descendents
$allItems = @( ($root.Axes.GetDescendants() | Initialize-Item))

# Get all including Home
$allItems = @($root) + @(($root.Axes.GetDescendants() | Initialize-Item))

$allItems | ForEach-Object {
# Get the items
$currentItem = $_

# Get item fields and create loop
$currentItem.Fields | ForEach-Object {
    
    #Check the field type
    if ($_.type -eq "Linklist") ## Here is where i would like to change the target value
    {
        
        [Sitecore.Data.Fields.LinkField]$linkField = $currentItem.Fields[$_.name]
        
        Write-Host "Processing link": $currentItem.Fields[$_.name]
        
        #Update target for Internal Links
        if ($linkField.Linktype -eq 'internal')
        {
            $currentItem.Editing.BeginEdit()
            $linkField.target = ""
            $currentItem.Editing.EndEdit()
        }
        
        Write-Host "Link Processed": $currentItem.Fields[$_.name]
       
    }

    if ($_.type -eq "General Link")
    {
        [Sitecore.Data.Fields.LinkField]$linkField = $currentItem.Fields[$_.name]
        # Update target for Internal Links
        if ($linkField.Linktype -eq 'internal')
        {
            $currentItem.Editing.BeginEdit()
            $linkField.target = ""
            $currentItem.Editing.EndEdit()
        }
    }
}
}  
}

We have a custom field type of "Linklist" which is basically just a set of normal link field XML values wrapped inside of links tags.

Example:

<links><link id="{3078F4A4-21C6-4086-B0BA-BCECBBA43A79}" querystring="" target="New 
Browser" text="testing 2" anchor="" url="" title="" class="" 
linktype="internal" /><link text="testing56" anchor="" linktype="internal" class="" 
title="" target="_blank" querystring="" id="{3078F4A4-21C6-4086-B0BA-BCECBBA43A79}" /> 
</links>

enter image description here

What i would like to do is when the script is checking if the field is a data type of linklist, i want to access this field and change all of the target values to an empty string ("")

Can anyone tell me the best way to do this?

Thanks!

3 Answers 3

1

Just place this inside if ($_.type -eq "Linklist") condition, it will modify only if linktype is internal

# Convert your linkList field raw value to xml
$xml=[XML]$currentItem.Fields[$_.name]
   
$nodes = $xml.SelectNodes("/links/link");

foreach($node in $nodes) {
    # check if linktype is internal
    if($node.GetAttribute("linktype") -eq 'internal')
    {
        $node.SetAttribute("target", "");
    }
}

    $currentItem.Editing.BeginEdit()
    $currentItem.Fields[$_.name] = $xml.outerxml
    $currentItem.Editing.EndEdit()

Write-Host "Link Processed": $currentItem.Fields[$_.name]

Hope this helps !

2
  • hi ive tested this piece of code however im getting the following error: ForEach-Object : Unable to index into an object of type Sitecore.Collections.FieldCollection. At line:16 char:27 + $currentItem.Fields | ForEach-Object {
    – user13705
    Nov 22, 2023 at 9:58
  • Was it working before ? Or it started breaking after you added above code ? Nov 22, 2023 at 11:00
1

Here is an example of reading your XML, checking all the target values, and updating them to blank.

[xml]$linkList = '<links><link id="{3078F4A4-21C6-4086-B0BA-BCECBBA43A79}" querystring="" target="New Browser" text="testing 2" anchor="" url="" title="" class="" linktype="internal" ></link><link id="{3078F4A4-21C6-4086-B0BA-BCECBBA43A79}" querystring="" target="New Browser" text="testing 2" anchor="" url="" title="" class="" linktype="internal" ></link></links>'

$xmlData =  [xml]$linkList

foreach($ver in $linkList.SelectNodes("links/*"))
{
    $ver.SetAttribute("target", "")
    Write-Host "attribute updated"
}

Write-Host $linkList.OuterXml

This will give you this output.

<links><link id="{3078F4A4-21C6-4086-B0BA-BCECBBA43A79}" querystring="" target="" text="testing 2" anchor="" url="" title="" class="" linktype="internal"></link><link id="{3078F4A4-21C6-4086-B0BA-BCECBBA43A79}" querystring="" target="" text
="testing 2" anchor="" url="" title="" class="" linktype="internal"></link></links>

You can also read the XML value from your field like this.

[xml]$linkList=$item.Fields["field name"]

Using the item update, you can update your custom field value with the new one. I guess using this example you will be able to complete your code.

Hope this helps.

1

It looks like you are on the right track, but you need to make a small adjustment to your code to handle the XML content within the "Linklist" field. You can use the [Sitecore.Data.Fields.XmlField] class to work with the XML content of the field.

Try to use below script:

 New-UsingBlock (New-Object Sitecore.Data.BulkUpdateContext) {

    # Get Home items
    $root = Get-Item -Path "master:/sitecore/content/sitename/Content/Common/Footer"
    # Get its descendents
    $allItems = @( ($root.Axes.GetDescendants() | Initialize-Item))

    # Get all including Home
    $allItems = @($root) + @(($root.Axes.GetDescendants() | Initialize-Item))

    $allItems | ForEach-Object {
        # Get the items
        $currentItem = $_

        # Get item fields and create loop
        $currentItem.Fields | ForEach-Object {

            # Check the field type
            if ($_.type -eq "Linklist") {
                [Sitecore.Data.Fields.XmlField]$xmlField = $currentItem.Fields[$_.name]

                Write-Host "Processing link": $currentItem.Fields[$_.name]

                # Update target for Internal Links
                $xmlContent = $xmlField.InnerXml
                $xmlDoc = New-Object System.Xml.XmlDocument
                $xmlDoc.LoadXml($xmlContent)

                foreach ($linkNode in $xmlDoc.SelectNodes("//link[@linktype='internal']")) {
                    $linkNode.SetAttribute("target", "")
                }

                $xmlField.InnerXml = $xmlDoc.OuterXml

                $currentItem.Editing.BeginEdit()
                $currentItem.Editing.EndEdit()

                Write-Host "Link Processed": $currentItem.Fields[$_.name]
            }

            if ($_.type -eq "General Link") {
                [Sitecore.Data.Fields.LinkField]$linkField = $currentItem.Fields[$_.name]
                # Update target for Internal Links
                if ($linkField.Linktype -eq 'internal') {
                    $currentItem.Editing.BeginEdit()
                    $linkField.target = ""
                    $currentItem.Editing.EndEdit()
                }
            }
        }
    }
}

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.