0

I have next XML file:

<root>
    <location id='IBM'>
        <property name='locale' value='en-EN' />
        <property name='path' value='c:\program files\IBM' />
        <property name='option' value='licence' />
        <package kind='offering' name='IBM tools'>
            <property name='cic.name' value='IBM Studio'/>
            <property name='cic.version' value='13.4'/>
        </package>
    </location>
    <location id='Microsoft'>
        <property name='locale' value='en-EN' />
        <property name='path' value='c:\program files\MS' />
        <property name='option' value='licence' />
        <package kind='offering' name='Microsoft'>
            <property name='cic.name' value='Windows XP'/>
            <property name='cic.version' value='10.3.2'/>
        </package>
    </location>
</root>

How I can get this values from cic.name and cic.version inside that XML structure:

IBM Studio 13.4 Windows Xp 10.3.2

I have tried this

XElement roots = XElement.Load(@"C:\test.xml");

foreach (var i in roots.Descendants("location"))
{
   Console.WriteLine(i.Attribute("id").Value);
}

But I get only: IBM Microsoft

Thank you!

Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116

3 Answers3

0

Here is the solution

var doc = XDocument.Load(yourXmlFilePath);

var packages = doc.Descendants("package")
                .Select(p => new
                {
                    Name = p.Elements("property")
                            .SingleOrDefault(i => i.Attribute("name")?.Value == "cic.name")
                            ?.Attribute("value")
                            ?.Value,
                    Version = p.Elements("property")
                               .SingleOrDefault(i => i.Attribute("name")?.Value == "cic.version")
                               ?.Attribute("value")
                               ?.Value
                }).ToList();

var result = names.Select(i => string.Format("{0} {1}", i.Name, i.Version)).ToList();

//result: "IBM Studio 13.4"
//        "Windows XP 10.3.2"
Hossein Narimani Rad
  • 31,361
  • 18
  • 86
  • 116
0

Your code only looks for id attributes on location elements.

If you want the cic.name and cic.version values, you'll have to include those in your query instead.

var results =
    from package in doc.Descendants("package")
    select new
    {
        Name = (string) package.Elements("property")
            .Where(x => (string) x.Attribute("name") == "cic.name")
            .Attributes("value")
            .Single(),
        Version = (string) package.Elements("property")
            .Where(x => (string) x.Attribute("name") == "cic.version")
            .Attributes("value")
            .Single(),
    };

See this fiddle for a demo.

Charles Mager
  • 25,735
  • 2
  • 35
  • 45
0

Try something like this

foreach (var Locations in roots.Descendants("location"))
{
    foreach (var item in Locations.Descendants("package"))
    {
        Console.WriteLine(item.Attribute("id").Value);
    }

}
Maddy
  • 774
  • 5
  • 14