Chat
Chat

Reputation: 185

ReplaceWith XElement

Below is the snippet of content of my XDocument .

    <p style="">
            <img id="Object3"  src="Object3_png16malpha.png" width="78" height="37" />
    </p>
    <p style="">
        <span>1 point: correct response of Point </span>X: 
        <img id="Object4"  src="Object4_png16malpha.png" width="76" height="37" /> Point y: 
        <img id="Object5"  src="Object5_png16malpha.png" width="78" height="37" /> Point z: 
        <img id="Object6"  src="Object6_png16malpha.png" width="78" height="37" />. 
        <span style="">(1 point).</span>
    </p>
<accessElement identifier="1234">
    <contentLinkInfo LinkIdentifierRef="9_BEGIN" type="Text">
        <objectLink />
    </contentLinkInfo>
</accessElement>

Basically I am trying to replace each image <img> tag with new content. For image <Tag> of Object3 looks as below after processing.

<span class="mathml" data-png="Object3_png16malpha.png" data-svg="Object3_png16malpha.svg">
    <img id="Object3" alt="" src="Object3_png16malpha.png" />
</span>

But below is the output I am getting which skips processing of some of image tags which I am not sure about.

<p style="">
        <span class="mathml" data-png="Object3_png16malpha.png" data-svg="Object3_png16malpha.svg">
            <img id="Object3" alt="" src="Object3_png16malpha.png" />
    </span>
</p>
<p style="">
    <span>1 point: correct response of Point </span>X: 
    <span class="mathml" data-png="Object4_png16malpha.png" data-svg="Object4_png16malpha.svg">
        <img id="Object4" alt="" src="Object4_png16malpha.png" />
    </span> Point y: 
    <img id="Object5"  src="Object5_png16malpha.png" width="78" height="37" /> Point z: 
    <img id="Object6"  src="Object6_png16malpha.png" width="78" height="37" />. 
    <span style="">(1 point).</span>
</p>
<accessElement identifier="1234">
    <contentLinkInfo LinkIdentifierRef="9_BEGIN" type="Text">
        <objectLink />
    </contentLinkInfo>
</accessElement>

Below is snippet of my code

  foreach (XElement bodyElement in uthDocument.Descendants().Elements())
        {
            if (bodyElement.Name == "img")
            {
                XElement newImageElement = getNewImageElement(bodyElement);
                bodyElement.ReplaceWith(newImageElement);
            }

        }

My code does skips the replacement of last two image elements.

Upvotes: 0

Views: 856

Answers (1)

Charles Mager
Charles Mager

Reputation: 26223

The structure of LINQ to XML Is akin to a linked list - each node holds a reference to its next node.

When you replace your original bodyElement with your new one, then the next node pointed to by bodyElement is now null as you've pulled it out of the tree. So, most likely, one of your iterators will then break and return at this point.

As an aside, you also don't need your Elements() call, as you'll end up iterating most elements more than once. Descendants() will return all elements below already.

So, just eagerly evaluate Descendants() and iterate that instead:

foreach (XElement bodyElement in uthDocument.Descendants().ToList())
{
    ...
}

Ideally you'd filter this before calling ToList(). Assuming this is XHTML this is fairly simple:

XNamespace xhtml = "http://www.w3.org/1999/xhtml";
var imgElements = uthDocument.Descendants(xhtml + "img").ToList();

Upvotes: 1

Related Questions