Posts Tagged XDocument

C#: Adding CData Sections to an Existing Node using XmlDocument and XDocument to handle HTML code or other problematic characters

There are situations where the data within nodes of Xml need to be handled due to special characters or html type tags. To handle that one must place data into CData sections. This artcle shows one how to do that in .Net using C# for both the XMLDocument as well as the XDocument.

XMLDocument Example

string myXml =
@"<?xml version='1.0' encoding='utf-8'?>
<WorkingSet>
 <Data>
 </Data>
</WorkingSet>";

XmlDocument doc1 = new XmlDocument();
doc1.LoadXml( myXml );

XmlNode target = doc1.SelectSingleNode( "WorkingSet/Data" );

if (target != null)
    target.AppendChild( doc1.CreateCDataSection( "<h1>Hello</h1>" ) );

XDocument Example

XDocument doc = XDocument.Parse( myXml, LoadOptions.SetLineInfo );

XElement dataNode = doc.Descendants( "Data" ).First();

dataNode.Add ( new XCData( "<h1>Hello</h1>" ));

Console.WriteLine( doc.ToString() );

Results

<?xml version="1.0" encoding="utf-8"?>
<WorkingSet>
 <Data><![CDATA[<h1>Hello</h1>]]></Data>
</WorkingSet>
Share

Tags: , ,

Tribal Knowledge: C# XDocument Copy Xml But Remove the Pesky DocType

stockxpertcom_id7474751_jpg_882845b5f523a87946c1e89ba7bb9621 In another of my series of Tribal Knowledge articles, this one discusses the basics of loading an XDocument and creating a different document from that original.

There may be a need for one to remove the document type from the original XDocument in C#, or do a basic copy and this is presented here.

How-To

Here is the Xml in a classic before:

<?xml version='1.0' encoding='utf-8'?>
<!-- Generator: AVG Magician 1.0.0, AVG Exports Plug-In . AVG Version: 2.00 Build 8675309)  -->
<!DOCTYPE svg PUBLIC '-//W3C//DTD AVG 1.1//EN' 'http://www.w3.org/Graphics/AVG/1.1/DTD/avg11.dtd'[]>
<avg version='1.1' id='Layer_1' x='0px' y='0px' xml:space='preserve'>
    <rect x='100.143' y='103.714' fill='none' width='87.857' height='12.143' />
</avg>

and this is what we want to achieve:

<?xml version='1.0' encoding='utf-8'?>
<avg version="1.1" id="Layer_1" x="0px" y="0px" xml:space="preserve">
    <rect x="100.143" y="103.714" fill="none" width="87.857" height="12.143" />
</avg>

Since we only care about the AVG node, its the main root, we will simply get that node and append it to our new clone. Here is the full code:

string xml = @"<?xml version='1.0' encoding='utf-8'?>
<!-- Generator: AVG Magician 1.0.0, AVG Export Plug-In . AVG Version: 2.00 Build 8675309)  -->
<!DOCTYPE svg PUBLIC '-//W3C//DTD AVG 1.1//EN' 'http://www.w3.org/Graphics/AVG/1.1/DTD/avg11.dtd'[]>
<avg version='1.1' id='Layer_1' x='0px' y='0px' xml:space='preserve'>
    <rect x='100.143' y='103.714' fill='none' width='87.857' height='12.143' />
</avg>";

XDocument loaded = XDocument.Parse( xml, LoadOptions.SetLineInfo );

XDocument clone = new XDocument( new XDeclaration( "1.0", "utf-8", "yes"),
    loaded.LastNode
    );

Console.WriteLine( clone );

The above achieves the after Xml which we seek, no DocType, we didn’t add it and no first node which is the comment line. I hope this little example helps.

Share

Tags: ,

C# XML Parsing Extracting Values and using XML to Linq with XDocument

On my blog the most accessed articles are the basic ones on XML which has suprised me. So In this article I will focus on the new kid on the block the Linq derived XDocument. In the following example I will load the Xml then enumerate over the child nodes, to extract specific values and then display them.

I am loading the xml directly, but you can load it from other locations using the Load option of XDocument.

string xml = @"<?xml version='1.0' encoding='UTF-8'?>
<widgets>
    <widget>
        <url>~/Portal/Widgets/ServicesList.ascx</url>
        <castAs>ServicesWidget</castAs>
        <urlType>ascx</urlType>
        <parameters>
            <PortalCategoryId>3</PortalCategoryId>
        </parameters>
    </widget>
    <widget>
        <url>www.omegacoder.com</url>
        <castAs>ServicesWidget</castAs>
        <urlType>htm</urlType>
        <parameters>
            <PortalCategoryId>41</PortalCategoryId>
        </parameters>
    </widget>
</widgets>";

XDocument loaded = XDocument.Parse( xml );

var widgets = from x in loaded.Descendants( "widget" )
              select new
              {
                  URL = x.Descendants( "url" ).First().Value,
                  Category = x.Descendants( "PortalCategoryId" ).First().Value
              };

foreach ( var wd in widgets )
    Console.WriteLine( "Widget at ({0}) has a category of {1}", wd.URL, wd.Category );

/* Outputs:

Widget at (~/Portal/Widgets/ServicesList.ascx) has a category of 3
Widget at (www.omegacoder.com) has a category of 41

*/
Share

Tags: , ,

XPath meets Linq To XML in C#

There are two technologies which I feel that every coder should learn regardless of the language one programs in…those are Regular Expressions and XPath.

XPath is a quirkier language than Regular Expressions, but it is the the linqua-franca for working with xml documents. By specifying an XPath query which mirrors the target nodes one can get nodes from an xml document to be processed in the code.

The forum poster had xml data with a missing node, he had a car example. He wanted all the parent car nodes which had three tires (child nodes) and did not have four. Three wheel cars verse four wheel cars.

The following C# shows how to manipulate the Xpath and retrieve the nodes needed. Note one uses an xml editor with Xpath editing to figure out the stranger derivations.

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

...

string xml= @"<?xml version='1.0' encoding='UTF-8'?>
<Main>
<cars>
    <car name='Twingo'>
        <wheel1>abc</wheel1>
        <wheel2>def</wheel2>
        <wheel3>ghi</wheel3>
    </car>
    <car name='quattro'>
        <wheel1>some info</wheel1>
        <wheel2>more info</wheel2>
        <wheel3>blur</wheel3>
        <wheel4>We have four tires</wheel4>
    </car>
    <car name='Triumph'>
        <wheel1>some info</wheel1>
        <wheel2>more info</wheel2>
        <wheel3>blur</wheel3>
    </car>
</cars>
</Main>";

XDocument loaded = XDocument.Parse( xml );

IEnumerable<XElement> list1
   = loaded.XPathSelectElements( "//cars/car[not(wheel4)]" );

foreach ( XElement el in list1 )
    Console.WriteLine( el );

/* Outputs
<car name="Twingo">
  <wheel1>abc</wheel1>
  <wheel2>def</wheel2>
  <wheel3>ghi</wheel3>
</car>
<car name="Triumph">
  <wheel1>some info</wheel1>
  <wheel2>more info</wheel2>
  <wheel3>blur</wheel3>
</car>*/
Share

Tags: , , ,