Uke
Uke

Reputation: 174

linq separate xml values in child nodes

I want to create a config file to validate userinputs. How do i access the different nodes - the value seems to be every node inside the element. I want to get the separate values to check inputs for length and the right format etc.

C#

var xml = XElement.Load (@"C:\Project\conf\config.xml");

foreach(var child in xml
                    .Element("Felder").Elements())
{
    string cld = child.Name + " " + child.Value;
}

xml:

<?xml version="1.0"?>
<Config>
    <Anrede>
        <key_1>Testval</key_1>
    </Anrede>
    <Felder>
        <KNR>
            <Length>6</Length>
            <Format>######</Format>
        </KNR>
        <AddressStatus>
            <Length>1</Length>
            <Format>0</Format>
        </AddressStatus>
        <adressResearch>
            <Length>1</Length>
            <Format>0</Format>
        </adressResearch>
        <AnredeNr>
            <Length>1</Length>
            <Format>0</Format>
        </AnredeNr>
    </Felder>
</Config>

Output:

KNR 6######
AddressStatus 10
adressResearch 10
AnredeNr 10

Desired Output: KNR [6,######] or even better KNR.Length = 6, KNR.Format = "######"

Is there a better way to write a config like this?

Upvotes: 0

Views: 325

Answers (3)

Maciej Los
Maciej Los

Reputation: 8591

If you would like to search Xml data for specific node to get its subnodes, you can use Linq to XML. For example:

XDocument xdoc = XDocument.Load(@"C:\Project\conf\config.xml");
string sSetting = "KNF";
string sSetting = "KNR";
var result = xdoc.Descendants("Felder").Descendants()
                 .Where(x=>x.Name == sSetting)
                 .Select(x=>new {
                        Length = x.Element("Length").Value, 
                        Format = x.Element("Format").Value
                    });

Result:

Length Format
6      ###### 

In case you want to get every node to be get list of setting's name, length and format, you can try this:

var result1 = xdoc.Descendants("Felder").Elements()
                .Select(x=>new
                    {
                        Name = x.Name,
                        Length = x.Element("Length").Value,
                        Format = x.Element("Format").Value
                    })
                .ToList();
foreach(var setting in result1)
{
    Console.WriteLine("{0} | {1} | {2}", 
                 setting.Name, setting.Length, setting.Format);
}

Upvotes: 0

Charles Mager
Charles Mager

Reputation: 26213

Value will return all descendant text nodes, hence when you're getting Value for e.g. KNR it returns 6######.

You need to access the child element values separately:

foreach(var field in xml.Element("Felder").Elements())
{
    var fieldName = field.Name.LocalName;
    var length = (int)field.Element("Length");
    var format = (string)field.Element("Format");

    // do what you want with these
    // or ...

    var childValues = field.Elements().Select(x => x.Value);
    var childValuesCommaSeparated = string.Join(","  childValues);        
}

Upvotes: 0

ASh
ASh

Reputation: 35680

this linq query (SelectMany in query syntax)

IEnumerable<DictionaryEntry> keyValuePairs = 
                from child in xml.Element("Felder").Elements()
                from tag in child.Elements()
                select new DictionaryEntry(String.Format("{0}.{1}", child.Name, tag.Name), tag.Value);

gives output for current xml structure (formatting may be different):

{ Key = KNR.Length, Value = 6 }
{ Key = KNR.Format, Value = ###### }
{ Key = AddressStatus.Length, Value = 1 }
{ Key = AddressStatus.Format, Value = 0 }
{ Key = adressResearch.Length, Value = 1 }
{ Key = adressResearch.Format, Value = 0 }
{ Key = AnredeNr.Length, Value = 1 }
{ Key = AnredeNr.Format, Value = 0 }

try it with a fiddle

Upvotes: 3

Related Questions