从XML和未知子项加上容器类型的LINQ查询?

时间:2013-11-26 11:16:11

标签: c# xml linq

我搜索并阅读了很多页面和主题,但没有找到适合我的答案。很抱歉,如果它在那里,我正在创建一个双重帖子。

无论如何,我的问题是读取XML源并以良好的格式从那里获取数据。 我的XML是这样的:

<Items>
<Item>
    <Type>Book</Type>
    <Name>Jabba the Puppett</Name>
    <Attributes>
        <Author>Author Name</Author>
        <Creator Role="Illustrator">Another Name</Creator>
    </attributes>
</Item>
<Item>
    <Type>Car</Type>
    <Name>BMW</Name>
    <Attributes>
        <Model>520i</Model>
        <Color>Red</Color>
        <Date Role="Year">2009</Date>
        <Date Role="First registration">2010</Date>
        <Color>Red</Color>
    </Attributes>
<Item>

我的目标是使用LINQ将数据转换为某种容器类型数组(可能包含另一个容器容器)。 问题部分是属性,还有一个选项,它们根本不存在。

当我得到这样的结果时,我会非常高兴:

 foreach (var oneItem in itemlist)
        {
            Console.WriteLine(oneItem.Name +" - "+ oneItem.Type);
            foreach (var attribute in oneItem.Attributes)
                Console.WriteLine(attribute.TagName +attribute.Role+attribute.TagValue);
        }

所有项目和每个属性(该项目的属性)的列表都跟随每个项目。 所以输出将是这样的:


Book - Jabba the Puppett
    Author: Author Name
    Creator Illustrator: Another Name
Car - BMW
    Model: 520i
    Color: Red
    Date Year: 2009
    Date First registration: 2010

1 个答案:

答案 0 :(得分:0)

首先,这里有几个问题:你的XML需要一点修复(见下文);您的示例首先列出name,然后列出type,但您的输出会反过来列出它们(很容易更改)。

XElement xml = XElement.Load(myXmlFile);
string tabSpacer = "\t";
foreach (var oneItem in xml.Elements("Item"))
{
    //check if the "Name" element exists
    string name = oneItem.Element("Name") == null ? "" : oneItem.Element("Name").Value;
    //check if the "Type" element exists
    string type = oneItem.Element("Type") == null ? "" : oneItem.Element("Type").Value;
    Console.WriteLine(name + " - " + type);

    //check if the "Item" element contains an "Attributes" element
    if (oneItem.Element("Attributes") != null)
    {
        //assumes at most one "Attribtues" element
        foreach (var attribute in oneItem.Element("Attributes").Elements())
        {
            string role = attribute.Attribute("Role") == null ? "" : attribute.Attribute("Role").Value;
            Console.WriteLine(tabSpacer + attribute.Name + " " + role + ": " + attribute.Value);
        }
    }
}

这是正确的XML:

<Items>
    <Item>
        <Type>Book</Type>
        <Name>Jabba the Puppett</Name>
        <Attributes>
            <Author>Author Name</Author>
            <Creator Role="Illustrator">Another Name</Creator>
        </Attributes><!--capital A missing-->
    </Item>
    <Item>
        <Type>Car</Type>
        <Name>BMW</Name>
        <Attributes>
            <Model>520i</Model>
            <Color>Red</Color>
            <Date Role="Year">2009</Date>
            <Date Role="First registration">2010</Date>
            <Color>Red</Color>
        </Attributes>
    </Item><!--tag not closed-->
</Items><!--tag missing-->