views:

43

answers:

2

I am performing XML Operations on an XHTML document utilizing Xml and Linq.

When converting it back to a String for outputting to a browser, it renders script tags in their original provided form when creating the XElement as <script />.

That prevents it being processed correctly by most browsers on the market.

I would like to perform the XElement to String conversion in a way that it outputs the script tag like this <script></script>

Can someone help me on that? Thanks in advance. :)

First edit Providing some more information, the data is coming from an xml field in a MSSQL 2008R2 database. It is loaded from the xml field as <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js" />

Second edit Working sample

using System;
using System.Linq;
using System.Xml.Linq;

namespace Test1
{
    class Test1
    {
        static void Main(string[] args)
        {
            XElement element = XElement.Parse("<div><script /><script>Test</script></div>");
            var EmptySet = (from e in element.DescendantsAndSelf()
                           where e.IsEmpty
                           select e);
            foreach(XElement e in EmptySet)
            {
                e.Value = String.Empty;
            }
            Console.WriteLine(element.ToString(SaveOptions.None));
        }
    }
}

And its results

<div>
  <script></script>
  <script>Test</script>
</div>
A: 

Using

XElement.Save(XmlWriter writer)

where as a XmlWriter's output you use StringWriter is fast and reliable way get what you want.

Dewfy
+1  A: 

Have you tried using SaveOptions.DisableFormatting?

I can't actually reproduce the problem, mind you... what XML operations are you performing? Are you creating the script element yourself? This works fine:

using System;
using System.Xml.Linq;

class Test
{
    static void Main()
    {
        XElement element = XElement.Parse("<script></script>");
        // Both of these write <script></script>
        Console.WriteLine(element.ToString(SaveOptions.None));
        Console.WriteLine(element.ToString(SaveOptions.DisableFormatting));
    }
}

(XDocument.Save and XElement.Save have the same options.)

EDIT: To change an element with no child nodes into one with a single empty text node, you can just set element.Value to "". For example:

XElement element = XElement.Parse("<script />");
Console.WriteLine(element.ToString()); // Prints <script />
element.Value = "";
Console.WriteLine(element.ToString()); // Prints <script></script>
Jon Skeet
Unfortunately, the xml is coming from a database so it is coming from the database as <script />When I put that in your Parse example, it outputs <script />.
Michael
@Michael: So it's not that it's *converting* the script tag to `<script />` - it's faithfully formatting the XML from the database.
Jon Skeet
Thanks for that, I have marked you as answer.As a quick question, if the script tag was a deep descendant XElement instead of being the parent, what is the easiest way to search the XElements to change all empty ones to have an empty string as per your example.
Michael
@Michael: Something like `doc.Descendants().Where(x => x.Value == "")` should work. You may want to materialize the query (convert it to a list) before modifying the elements. Note that fetching the `Value` property returns "" instead of null even if there are no children, as far as I've seen.
Jon Skeet
Thanks for your help Jon. :)I found that testing on IsEmpty returns whether it is empty or not, so I have done the correction onto that and gotten it working how I wanted it to.
Michael
@Michael: Whoops, I hadn't spotted IsEmpty. I'd personally not bother using a query expression there: `var emptySet = element.DescendantsAndSelf().Where(e => e.IsEmpty).ToList();`
Jon Skeet