views:

852

answers:

6

I'd like to convert an external XML document without any XSD schema associated with it into a fluent .NET object.

I have a simple XML file like:

<application>
    <parameters>
        <param></param>
        <param></param>
    </parameters>
    <generation />
    <entities>
        <entity ID="1">
            <PropTest>Test</PropTest>
        </entity>
        <entity ID="2">
            <PropTest>Another Test</PropTest>
        </entity>
     </entities>
</application>

I'd like to navigate the document like:

var xConfig = new XmlConfig("file.xml");

// testValue should be assigned "Test"
string testValue = xConfig.Generation.Entities.Entity(1).PropTest;

What is the best way to achieve this in .NET 3.5?

+1  A: 

I would look at xsd.exe. You can also go here for a more informative tutorial on how to use it.

Basically you will be create .NET class equivalents of your XSD. You will then be able to serialize and deserialize your XML and objects.

Andrew Hare
There is no XSD designer in Visual Studio 2008: http://stackoverflow.com/questions/746673/xml-schema-designer-for-visual-studio-2008 Are there other good, free options?
Alex Angas
A: 

If you just extract the schema(which should be easy with xsd.exe) then this online tool (which can also be downloaded) could help you, I tried it and it's ok.

pablito
+2  A: 

Arguably, the best way to do this these days is with Linq to XML. It is a whole lot easier than messing with XSDs and convoluted class definitions.

XDocument doc = XDocument.Load("file.xml");
var val = doc
    .Descendants("entity")
    .Where(p => p.Attribute("ID").Value == "1")
    .Descendants("PropTest")
    .FirstOrDefault();
if (val != null)
    Console.WriteLine(val.Value);

The sample file.xml that I used was:

<?xml version="1.0" encoding="utf-8" ?>
<application>
    <parameters>
        <param></param>
        <param></param>
    </parameters>
    <generation>
        <entities>
            <entity ID="1">
                <PropTest>Test</PropTest>
            </entity>
            <entity ID="2">Another Test</entity>
        </entities>
    </generation>
</application>
Lusid
That's much less readable than the example given in the question. Is this really the best we can do with LINQ?
Alex Angas
The example given in the question assumes there is a set of strongly typed classes that have been generated to match the XML structure being loaded. Since we aren't capable of building dynamic classes (yet), then yes, this is the best we can do with LINQ. Dynamic languages like Ruby and PHP could do this with a fluent syntax like he is describing on the fly without necessarily knowing the schema ahead of time.
Lusid
+2  A: 

I just noticed that Lusid also wrote about Linq to SQL while I was writing my answer, but he used XDocument.

Here is my version (file.xml is the XML given in the question):

string testValue =
    (string) XElement.Load("file.xml")
     .Element("entities")
     .Elements("entity")
     .FirstOrDefault(entity => entity.Attribute("ID")
      .Value == "1") ?? string.Empty;
Presidenten
A: 

Define classes derived from ConfigurationSection/ConfigurationElement etc. They map to xml files nicely (that's what they'r built for) See MSDN for this. Another way is to create POCO objects and set XML serialization attributes over properties then use System.XML.XMLSerializer to serialize/deserialize to/from XML. See MSDN for XML Serialization.

AZ
A: 

Kevin Hazzard has written a fluent XML interface for C# using the .NET 4.0 dynamic type part 1 and part 2. This would allow code like:

var v = dx.application.entities.entity[0].PropTest.Value;
Alex Angas