Showing posts with label XML. Show all posts
Showing posts with label XML. Show all posts

Thursday, June 19, 2008

DataSet to XmlDocument and Back

To convert your DataSet into an XmlDocument:
MyDataSet myDataSet = new MyDataSet();
// Add rows to the DataTables in myDataSet

XmlDocument myXmlDocument = new XmlDocument();
myXmlDocument.LoadXml(myDataSet.GetXml());
To convert your XmlDocument into a DataSet:
MyDataSet myDataSet = new MyDataSet();

myDataSet.ReadXml(new MemoryStream((new UTF8Encoding()).GetBytes(myXmlDocument.OuterXml)));


More Info:MSDN: XmlDocument.LoadXml Method
MSDN: DataSet.ReadXml Method (Stream)

Monday, May 5, 2008

XDocument - Selecting a multiple elements

Say we want to select all Person elements in this XML:
<Persons>
  <Person>
    <PersonId>1</PersonId>
    <PersonName>Mark</PersonName>
  </Person>
  <Person>
    <PersonId>2</PersonId>
    <PersonName>Matt</PersonName>
  </Person>
</Persons>
You can use the following code:
string returnValue = string.Empty;
XDocument ds = XDocument.Load("MyXml.xml");
var people = ds.Element("Persons").Elements("Person");

foreach (var singlePerson in people)
{
    returnValue += singlePerson.Element("PersonName").Value + "\r\n";
}

Console.WriteLine(returnValue);
The result will be:
Mark
Matt


More Info: MSDN: XContainer.Elements Method

Thursday, May 1, 2008

XDocument - Selecting a single element value

XDocument is a new class that represents an XML document. It's a replacement to the XmlDocument and falls under the System.XML.LINQ namespace. When it comes time to selecting node values, you can say good-bye to XPath. Here is an example of selecting just one value from XML.
<Persons>
  <Person>
    <PersonId>1</PersonId>
    <PersonName>Mark</PersonName>
  </Person>
  <Person>
    <PersonId>2</PersonId>
    <PersonName>Matt</PersonName>
  </Person>
</Persons>
Say you want to select the first PersonName. You can write code like this:
XDocument ds = XDocument.Load("MyXml.xml");
string value = ds.Element("Persons").Element("Person").Element("PersonName").Value;
When you look for Element("Persons"), the XDocument is going to search for the FIRST match.

More Info: MSDN: XContainer.Element Method

Wednesday, April 30, 2008

LINQ to XML - Namespaces

Adding on to yesterday's post, you might come across xml that has a namespace defined. You'll have to handle this with the XNamespace object.
XML with namespace:
<?xml version="1.0" standalone="yes"?>
<MyDataSet xmlns="http://tempuri.org/MyDataSet.xsd">
  <Person>
    <PersonId>1</PersonId>
    <PersonName>Mark</PersonName>
  </Person>
  <Person>
    <PersonId>2</PersonId>
    <PersonName>Matt</PersonName>
  </Person>
</MyDataSet>
Querying the XML:
XDocument ds = XDocument.Load(Resources.SimpleXmlFileWithNamespacePath);
XNamespace ns = "http://tempuri.org/MyDataSet.xsd";
XName xNamePerson = ns + "Person";
XName xNamePersonName = ns + "PersonName";

var personNames = from person in ds.Descendants(xNamePerson)
              select new
              {
                  PersonName = person.Element(xNamePersonName).Value
              };
The XName class provides a way to combine a namespace and an element name.

More Info: MSDN: XNamespace Class
MSDN: XName Class

Tuesday, April 29, 2008

LINQ to XML

There's a lot you can do with LINQ to XML. It will be your alternative to selecting xml nodes using XPath queries. I'm going to show you just a little bit at a time.

Say you wanted to get all PersonName values from this xml:
<Persons>
  <Person>
    <PersonId>1</PersonId>
    <PersonName>Mark</PersonName>
  </Person>
  <Person>
    <PersonId>2</PersonId>
    <PersonName>Matt</PersonName>
  </Person>
</Persons>
You can simply write your LINQ like this:
XDocument ds = XDocument.Load("PersonsFile.xml");

var persons = from eachPerson in ds.Descendants("Person") 
select new 
{
    PersonName = eachPerson.Element("PersonName").Value
};
This is two lines of code. Notice the semicolon at the very end.

XDocument is like your new XmlDocument class. It loads an xml file.
LINQ is then used to find all elements (descendants) that are named "Person".

So what the heck is happening with that select new? Remember the post on anonymous types? That's what this LINQ to XML is creating; a collection of anonymous types (classes). The breakdown of what this LINQ statement is saying:
1. Give me a collection of elements that match "Person" which you can reference from the eachPerson variable.
2. Create an anonymous class and add a property called "PersonName".
3. "PersonName" is assigned a value from the eachPerson match.
4. Now add that new anonymous class to the var collection called "persons".

The result is a collection of typed objects that you can iterate through later on:
List<string> array = new List<string>();
foreach (var person in persons)
{
    array.Add(person.PersonName);
}

This is a whole different shift in thinking. To get used to it I suggest you write some code and create a bunch of anonymous classes until you are comfortable with that concept. Create anonymous classes, add properties. Access and use those properties and so on. Once you feel good and comfortable with that you can move on to learning more about LINQ.
More Info: MSDN:

Friday, April 25, 2008

XmlWriter

To create this in code:
<?xml version="1.0" encoding="utf-16"?><Person><FirstName>Mark</FirstName><LastName>Moeykens</LastName></Person>
You can code it this way:
StringBuilder sb = new StringBuilder();
using(XmlWriter writer = XmlTextWriter.Create(sb))
{
    writer.WriteStartElement("Person");
    writer.WriteElementString("FirstName", "Mark");
    writer.WriteElementString("LastName", "Moeykens");
    writer.WriteEndDocument();
}
Console.Write(sb.ToString());
The
<?xml version="1.0" encoding="utf-16"?>
bugs me though. I never seem to have a use for it in my code so let's get rid of it.

To do that, we have to introduce some settings for our writer using the XmlWriterSettings class then pass it into the XmlTextWriter.Create method.
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;

StringBuilder sb = new StringBuilder();
using(XmlWriter writer = XmlTextWriter.Create(sb, settings))
{
    writer.WriteStartElement("Person");
    writer.WriteElementString("FirstName", "Mark");
    writer.WriteElementString("LastName", "Moeykens");
    writer.WriteEndDocument();
}
Console.Write(sb.ToString());
Output:
<Person><FirstName>Mark</FirstName><LastName>Moeykens</LastName></Person>
That's better. Now let's add another setting to get the elements on their own line and indented:
XmlWriterSettings settings = new XmlWriterSettings();
settings.OmitXmlDeclaration = true;
settings.Indent = true;

StringBuilder sb = new StringBuilder();
using(XmlWriter writer = XmlTextWriter.Create(sb, settings))
{
    writer.WriteStartElement("Person");
    writer.WriteElementString("FirstName", "Mark");
    writer.WriteElementString("LastName", "Moeykens");
    writer.WriteEndDocument();
}
Console.Write(sb.ToString());
Output:
<Person>
  <FirstName>Mark</FirstName>
  <LastName>Moeykens</LastName>
</Person>
There we go, this looks much better!

More Info: MSDN: Creating XML Writers