Xdocument or Xmldocument

XDocument or XmlDocument

If you're using .NET version 3.0 or lower, you have to use XmlDocument aka the classic DOM API. Likewise you'll find there are some other APIs which will expect this.

If you get the choice, however, I would thoroughly recommend using XDocument aka LINQ to XML. It's much simpler to create documents and process them. For example, it's the difference between:

XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("root");
root.SetAttribute("name", "value");
XmlElement child = doc.CreateElement("child");
child.InnerText = "text node";
root.AppendChild(child);
doc.AppendChild(root);

and

XDocument doc = new XDocument(
new XElement("root",
new XAttribute("name", "value"),
new XElement("child", "text node")));

Namespaces are pretty easy to work with in LINQ to XML, unlike any other XML API I've ever seen:

XNamespace ns = "http://somewhere.com";
XElement element = new XElement(ns + "elementName");
// etc

LINQ to XML also works really well with LINQ - its construction model allows you to build elements with sequences of sub-elements really easily:

// Customers is a List<Customer>
XElement customersElement = new XElement("customers",
customers.Select(c => new XElement("customer",
new XAttribute("name", c.Name),
new XAttribute("lastSeen", c.LastOrder)
new XElement("address",
new XAttribute("town", c.Town),
new XAttribute("firstline", c.Address1),
// etc
));

It's all a lot more declarative, which fits in with the general LINQ style.

Now as Brannon mentioned, these are in-memory APIs rather than streaming ones (although XStreamingElement supports lazy output). XmlReader and XmlWriter are the normal ways of streaming XML in .NET, but you can mix all the APIs to some extent. For example, you can stream a large document but use LINQ to XML by positioning an XmlReader at the start of an element, reading an XElement from it and processing it, then moving on to the next element etc. There are various blog posts about this technique, here's one I found with a quick search.

Converting XDocument to XmlDocument and vice versa

You can use the built in xDocument.CreateReader() and an XmlNodeReader to convert back and forth.

Putting that into an Extension method to make it easier to work with.

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

namespace MyTest
{
internal class Program
{
private static void Main(string[] args)
{

var xmlDocument = new XmlDocument();
xmlDocument.LoadXml("<Root><Child>Test</Child></Root>");

var xDocument = xmlDocument.ToXDocument();
var newXmlDocument = xDocument.ToXmlDocument();
Console.ReadLine();
}
}

public static class DocumentExtensions
{
public static XmlDocument ToXmlDocument(this XDocument xDocument)
{
var xmlDocument = new XmlDocument();
using(var xmlReader = xDocument.CreateReader())
{
xmlDocument.Load(xmlReader);
}
return xmlDocument;
}

public static XDocument ToXDocument(this XmlDocument xmlDocument)
{
using (var nodeReader = new XmlNodeReader(xmlDocument))
{
nodeReader.MoveToContent();
return XDocument.Load(nodeReader);
}
}
}
}

Sources:

  • http://msdn.microsoft.com/en-us/library/bb356384.aspx
  • http://geekswithblogs.net/aspringer/archive/2009/07/01/xdocument-extension.aspx

XDocument or XmlDocument to JSON with C#

Use the method call

JsonConvert.SerializeXNode(x, Formatting.None, true);

this will omit the root node and should create what you expect.

How to change from XDocument to XMLDocument Code?

A basic example of this would be:

List<string> valueNames = new List<string>();
List<string> headingNames = new List<string>();

XmlDocument doc = new XmlDocument();
doc.Load("data.xml");

for (int r = 0; r < doc.ChildNodes.Count; r++)
{
var currentNode = doc.ChildNodes.Item(r);
if (currentNode.Name.Equals("ROOT"))
{
var columnsNode = currentNode.FirstChild;

for (int i = 0; i < columnsNode.ChildNodes.Count; i++)
{
XmlNode child = columnsNode.ChildNodes.Item(i);

for (int j = 0; j < child.Attributes.Count; j++)
{
var attribute = child.Attributes.Item(j);
if (attribute.Name.Equals("XPath"))
{
headingNames.Add(attribute.Value);
}
else if (attribute.Name.Equals("Name"))
{
valueNames.Add(attribute.Value);
}
}
}
}
}

Some explanation:

  • Your example XML has no XML Declaration, so we can get the Root Element simply be accessing the FirstChild property.

  • After Edit: Your example XML has now a XML Declaration, but the pattern is the same. For-Loop and accessing Child Elements per Indexer of this loop.

  • The 'Columns' Element can be reached the same way.

  • On the 'Columns' Element we for-loop through all Child Nodes and using the indexer (i) of our loop to get the corresponding element. Why? Because it's an XmlNodeList Object.

  • With our XmlNode child we do the same, but this time not with Child Nodes. Instead we loop through the Attribute Nodes and looking for the correct name.

Convert XMLDocument to XDocument ,getting names spaces Modifing from xsi to p1

You need to explicitly add the xsi namespace declaration manually at the beginning of your element.

Nodes are processed in document order and the namespace declaration appears later after it is first used. It doesn't know to use xsi for the prefix until it's too late.

var doc = new XmlDocument();
doc.AppendChild(doc.CreateXmlDeclaration("1.0", "utf-8", null));
var root = (XmlElement)doc.AppendChild(doc.CreateElement("BMECAT"));
var xsi = "http://www.w3.org/2001/XMLSchema-instance";
root.SetAttribute("xmlns:xsi", xsi); //set the namespace now
root.SetAttribute("schemaLocation", xsi, "http://www.adlnet.org/xsd/adlcp_v1p3");
root.SetAttribute("version", "2005");


Related Topics



Leave a reply



Submit