Search code examples
c#xmlxelement

Strange result when adding HTML string to XElement


SOLVED: The problem was that I had my parenthesis in the wrong place. I had:

if (!String.IsNullOrEmpty(Text)) xElement.Add(new XElement("rtf"), Text);

Instead of:

if (!String.IsNullOrEmpty(Text)) xElement.Add(new XElement("rtf", Text));

I have a string (called Text, in my program) that looks like this:

<p _triv="1" style="text-align:left"><span style="font-family:'Verdana',sans serif;font-size:11pt;color:#FFFFFF">This is another text block.</span></p>

I need to add this exact string to an XElement called rtf. In my program, I'm doing it like this:

if (!String.IsNullOrEmpty(Text)) xElement.Add(new XElement("rtf"), Text);

I'd like the result to look like this: <rtf>&lt;p _triv="1" style="text-align:left"&gt;&lt;span style="font-family:'Verdana',sans serif;font-size:11pt;color:#FFFFFF"&gt;This is another text block.&lt;/span&gt;&lt;/p&gt;</rtf>

However, after running my program, the result looks like this (with the rtf node being malformed, and affecting the following nodes:

<text bordertype="ridge" defaulttext="" id="18748" idbefore="1" labelobject="18357"  nohtmlpreload="false" ontop="false" outline="true" parent="3" proportional="false">
  <name>Text Block 2</name>
    <lastupdated>1393440325</lastupdated>
    <transitionin>
      <transtype>32</transtype>
      <delay>3</delay>
      <speed>10</speed>
    </transitionin>
    <transitionout>
      <transtype>32</transtype>
      <delay>5</delay>
      <speed>10</speed>
    </transitionout>
    <possize>
      <point>
        <x>370</x>
        <y>467</y>
      </point>
      <size>
        <cx>200</cx>
        <cy>100</cy>
      </size>
    </possize>
    <rtf />&lt;p _triv="1" style="text-align:left"&gt;&lt;span style="font-family:'Verdana',sans serif;font-size:11pt;color:#FFFFFF"&gt;This is another text block.&lt;/span&gt;&lt;/p&gt;<bordercolor />000000<outlinecolor />FFFFFF<bordersize />1<marginsize />2</text>

Am I adding the string to the node wrong? For clarity, here's my whole method and the resulting XML that I'd like to have:

public XElement CreateNode()
{
    var xElement = new XElement("text");
    if (BorderType != null) xElement.Add(new XAttribute("bordertype", BorderType));
    if (DefaultText != null) xElement.Add(new XAttribute("defaulttext", DefaultText));
    if (LabelObject != null) xElement.Add(new XAttribute("labelobject", LabelObject));
    if (Outline != null) xElement.Add(new XAttribute("outline", Outline));
    if (SchemaVersion != null) xElement.Add(new XAttribute("schemaver", SchemaVersion));
    if (TextBlockType != null) xElement.Add(new XAttribute("textblocktype", TextBlockType));
    if (ShowVerticalScrollBar == true) xElement.Add(new XAttribute("verticalscroll", ShowVerticalScrollBar));
    base.CreateNode(ref xElement);
    if (!String.IsNullOrEmpty(Text)) xElement.Add(new XElement("rtf"), Text);
    if (BorderColor != null) xElement.Add(new XElement("bordercolor"), BorderColor);
    if (OutlineColor != null) xElement.Add(new XElement("outlinecolor"), OutlineColor);
    if (BorderSize != 0) xElement.Add(new XElement("bordersize"), BorderSize);
    if (MarginSize != 0) xElement.Add(new XElement("marginsize"), MarginSize);

    // This routine will sort the XAttributes of the XElement     
    var xdoc = new XDocument();
    xdoc.Add(xElement);
    Interface.Sort(xdoc);

    return xElement;
}

Expected result:

<text bordertype="ridge" defaulttext="" id="18748" idbefore="1" labelobject="18357" nohtmlpreload="false" ontop="false" outline="true" parent="3" proportional="false">
    <name>Text Block 2</name>
    <lastupdated>1393440325</lastupdated>
    <transitionin>
        <transtype>32</transtype>
        <delay>3</delay>
        <speed>10</speed>
    </transitionin>
    <transitionout>
        <transtype>32</transtype>
        <delay>5</delay>
        <speed>10</speed>
    </transitionout>
    <possize>
        <point>
            <x>370</x>
            <y>467</y>
        </point>
        <size>
            <cx>200</cx>
            <cy>100</cy>
        </size>
    </possize>
    <rtf>&lt;p _triv="1" style="text-align:left"&gt;&lt;span style="font-family:'Verdana',sans serif;font-size:11pt;color:#FFFFFF"&gt;This is another text block.&lt;/span&gt;&lt;/p&gt;</rtf>
    <bordercolor>000000</bordercolor>
    <outlinecolor>FFFFFF</outlinecolor>
    <bordersize>1</bordersize>
    <marginsize>2</marginsize>
</text>

Also, I tried to do this:

if (!String.IsNullOrEmpty(Text)) xElement.Add(new XElement("rtf"), XElement.Parse(Text));

But the results were still off (notice that rtf is malformed):

<text bordertype="ridge" defaulttext="" id="18748" idbefore="1" labelobject="18357" nohtmlpreload="false" ontop="false" outline="true" parent="3" proportional="false">
  <name>Text Block 2</name>
  <lastupdated>1393440325</lastupdated>
  <transitionin>
    <transtype>32</transtype>
    <delay>3</delay>
    <speed>10</speed>
  </transitionin>
  <transitionout>
    <transtype>32</transtype>
    <delay>5</delay>
    <speed>10</speed>
  </transitionout>
  <possize>
    <point>
      <x>370</x>
      <y>467</y>
    </point>
    <size>
      <cx>200</cx>
      <cy>100</cy>
    </size>
  </possize>
  <rtf />
  <p _triv="1" style="text-align:left">
    <span style="font-family:'Verdana',sans serif;font-size:11pt;color:#FFFFFF">This is another text block.</span>
  </p>
  <bordercolor />000000<outlinecolor />FFFFFF<bordersize />1<marginsize />2</text>

Solution

  • Use

    if (!String.IsNullOrEmpty(Text)) xElement.Add(new XElement("rtf", Text));
    

    instead of

    if (!String.IsNullOrEmpty(Text)) xElement.Add(new XElement("rtf"), Text);
    

    See: new XElement("rtf", Text)