C# XDocument issue

Soldato
Joined
20 Oct 2008
Posts
12,082
Just on the off chance...

I'm creating an xml file in C# using XDocument.

I've got one XElement where there's some text that needs splitting over two lines so the application I'm sending the file to will handle it as I'd like.

I want to end up with something like:

Code:
<Details>Line 1 
Line 2</Details>

If I try to insert the
directly I end up with:

Code:
<Details>Line 1 &amp;#xD;&amp;#xA;"Line 2</Details>

I can understand why it's escaping the ampersands, but can't see an obvious way to avoid it.

If I just use \r\n or Environment.NewLine they get passed through unmolested. I want them encoding, and at the moment I can't see how.

Does anyone have any thoughts while I sleep on it?

Thanks
 
Caporegime
Joined
18 Oct 2002
Posts
29,491
Location
Back in East London
I don't see why you are inserting encoded values. Just send \r\n as normal text.

Failing that.. the actual encoding for them is not what you are using, it is <&>#10; for LF
and <&>;#13; for CR

e: It's also quite presumptuous to assume they are using a Windows OS, too!
e2: Bloody forums decoded them! Remove the pointy brackets.
 
Last edited:
Soldato
OP
Joined
20 Oct 2008
Posts
12,082
The xml is only used internally for interfacing between two systems. I'm 100% sure that it's a Windows platform and that I need CRLF rather than just LF.

If I just use \r\n one of the applications in the chain converts the CRLF to LF. If I hand create an xml file with the encoded characters everything works as I want.

#10 is the same as #xA it's just decimal vs hexadecimal, the same with #13 and #xD.

I had play with using CData but ended up with:

Code:
<Details>Line 1<![CDATA[
]]>Line 2</Details>

I've ended up embedding my own code into the XDocument where I want the CRNL to appear. Eg:

Code:
<Details>Line 1_!#CRNL%!_Line 2</Details>
I then convert the XDocument to string and perform a replace:

Code:
string s = xDocument.ToString().Replace("_!#CRNL%!_", "
");
File.WriteAllText(filePath, s);

I'm sure there must be a more elegant solution, but this does at least work.
 
Last edited:
Soldato
Joined
23 Feb 2009
Posts
4,976
Location
South Wirral
Did you try the whole String as a CDATA section, not just the awkward characters ?

i.e.
Code:
<Details><![CDATA[Line 1
Line 2]]></Details>

XML parsers should respect the CDATA section as part of the standard, but I don't remember offhand if they are supposed to handle them inside element content or only the entire content.

I guess its down to how the application in the chain that's stuffing it up for you is handling it.
 
Soldato
OP
Joined
20 Oct 2008
Posts
12,082
I haven't tried putting it all in the CDATA.

There's a chance that the text I'm dealing with could contain characters that I do want encoding. I can virtually guarantee that ampersand will turn up on a fairly regular basis.
 
Associate
Joined
7 Nov 2013
Posts
255
Location
Kent, England
If you want control over the created XML then you should be using an implementation of XmlWriter. The following should achieve what you require:

Code:
var xDocument = new XDocument();

var xElement = new XElement("Details", "Line 1\r\nLine 2");
xDocument.Add(xElement);

var sb = new StringBuilder();
using (var writer = new StringWriter(sb))
{
    var xmlWriterSettings = new XmlWriterSettings { NewLineHandling = NewLineHandling.Entitize };
    using (var xmlWriter = XmlTextWriter.Create(writer, xmlWriterSettings))
    {
        xDocument.Save(xmlWriter);
    }
}

var xml = sb.ToString();

This will encode the \r as <&>#xD; and leave the \n as is, it seems this is fine for your needs anyway (the other application retains the LF).

If you don't want the xml declaration then add xmlWriterSettings.OmitXmlDeclaration = true;

This is assuming you are after the string, if you are writing to a Stream or TextWriter then use one of the other overloads of XmlTextWriter.Create and remove the StringBuilder and StringWriter.
 
Last edited:
Back
Top Bottom