3

I need to remove empty <p> tags from all rich text fields in the content tree:

<p>&nbsp;</p>

I've done nothing myself with Sitecore Powershell Extensions so far, so I am not sure if this is possible.

I've created a saveitempipeline so that this can't happen anymore, but we have a lot of fields with empty <p> tags so I'd like to remove them with SPE.

7

You can use the below script to remove all empty p/P tags (having space or &nbsp;).

This script uses the HtmlDecode method of System.Web.HttpUtility class to decode single or multiple occurrences of &nbsp; to an empty string and then Regex replaces p tags with or without spaces.

$items = Get-ChildItem "master:/sitecore/content" -Recurse -Language *

foreach($item in $items){
    Write-Host "Item  - " $item.Paths.Path
    foreach($field in $item.Fields){

        if($field.Type -eq "Rich Text"){

            $rawValue = $field.Value

            if($rawValue -like '*<p*'){
                $output = [System.Web.HttpUtility]::HtmlDecode($rawValue)
                $output =  $output -replace "(<(P|p)>)\s*(<\/(P|p)>)",'' #To remove <p></p> or <p> {HAVING SPACES IN BETWEEN} </p> or <P></P> or <P>  {HAVING SPACES IN BETWEEN}  </P>
                $output =  $output -replace "(<(P|p)\s*\/>)",''          #To remove self closed p tags e.g.  <p/> or <p         />

                $item.Editing.BeginEdit()
                $item.Fields[$field.Name].Value = $output
                $item.Editing.EndEdit()

                Write-Host "Field - " $field.Name 
                Write-Host ""
            }
        }
    }
}

Tested with

<p>p tag with text</p><p/><p /><p></p><div>hello</div><p>&nbsp;&nbsp;&nbsp;</p>

Output

<p>p tag with text</p><div>hello</div>
2

Here is another take at solving this problem.

  • Use the HtmlAgilityPack (included with Sitecore) to parse the document
  • Check for each required scenario with a function
  • Save some time by only looking at known fields

Test Html

<div>Here is something</div>
<p></p>
<p>&nbsp;</p>
<p>&nbsp; </p>
<p> &nbsp;</p>
<p>  &nbsp;&nbsp;</p>
<div>Something here<p>  &nbsp;&nbsp;</p></div>
<p>Here is something interesting</p>
<ul>
    <li></li>
</ul>
<p><span></span></p>
<p><span>Some text</span></p>

Sample Script

function Remove-EmptyPTag {
    param(
        [string]$Text
    )
    $htmlDocument = New-Object -TypeName HtmlAgilityPack.HtmlDocument
    $htmlDocument.LoadHtml($Text)
    $pNodes = $htmlDocument.DocumentNode.SelectNodes("//p")
    foreach($x in $pNodes) {
        # If the node is completely empty then we should remove
        if([string]::IsNullOrEmpty($x.InnerText)) {
            $x.Remove()
            continue
        }
        # If the node is only made up of spaces then we should remove
        if($x.InnerText -match "^(&nbsp;|\s)*$") {
            $x.Remove()
            continue
        }
    }
    # Found that once the p node is removed you ended up with some empty nodes in the final document.
    $count = $htmlDocument.DocumentNode.ChildNodes.Count
    $nodes = [HtmlAgilityPack.HtmlNode[]]::new($count)
    $htmlDocument.DocumentNode.ChildNodes.CopyTo($nodes, 0)
    foreach($node in $nodes) { 
        if([string]::IsNullOrWhiteSpace($node.InnerText)) {
            $htmlDocument.DocumentNode.RemoveChild($node)
        }
    }

    $htmlDocument.DocumentNode.OuterHtml
}

Get-Item -Path "master:" -ID "{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}" |
    ForEach-Object { $_.Content = Remove-EmptyPTag -Text $_.Content }
  • Nice one! but I think regex needs a small fix to handle another empty p scenarios where there is a space before &nbsp; or space between multiple &nbsp; – Surya Sep 7 at 21:27
  • Thanks Surya. Realized I needed the '|' pipe character to allow for any position. – Michael West Sep 8 at 1:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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