LINQtoXML嵌套集合和值?

时间:2010-09-20 20:13:44

标签: xml linq linq-to-xml

我有一些XML:

<Request>       
        <EmailAddress>string</EmailAddress>
        <Item>
            <name>FirstName</name>
            <value>John</value>
        </Item>
        <Item>
            <name>LastName</name>
            <value>Doe</value>
        </Item>
    </Request>

我的对象:

public class TheObject{
         public string EmailAddress { get; set; }
        public string SkuNumber { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
}

我想使用LINQtoXML从上面的XML中提取FirstName和LastName值来构建对象。我该怎么做?

更新:这是我开始的代码:

var object =
                xml.Descendants("Request").Select(
                    x =>
                    new TheObject()
                        {
                            EmailAddress = x.Element("EmailAddress").Value.ToString(),
                            SkuNumber = x.Element("SKU").Value.ToString(),
                            FirstName = ...,
                            LastName = ....

                        })

3 个答案:

答案 0 :(得分:1)

正如其他人指出的那样,如果你能控制XML结构,你可以更好地优化这种类型的查询。但是如果您坚持使用它并且想要在单个LINQ to XML中处理它,您可以执行以下操作(为了简洁起见,我省略了空引用/异常处理,具体取决于您可能希望将其扩展为覆盖的模式)这些领域)

class Program
{
    static void Main(string[] args)
    {
        var requestXml = XDocument.Parse(@"<Request>       
                                            <EmailAddress>string</EmailAddress>
                                            <Item>
                                                <name>FirstName</name>
                                                <value>John</value>
                                            </Item>
                                            <Item>
                                                <name>LastName</name>
                                                <value>Doe</value>
                                            </Item>
                                            </Request>");

        var request = (from req in requestXml.Descendants("Request")
                       select new TheObject
                       {
                           FirstName = (from item in req.Descendants("Item")
                                              where item.Element("name").Value == "FirstName"
                                              select item.Element("value").Value).First(),
                           LastName = (from item in req.Descendants("Item")
                                       where item.Element("name").Value == "LastName"
                                       select item.Element("value").Value).First(),
                           EmailAddress = req.Element("EmailAddress").Value
                       }
                       ).First();

    }
}

public class TheObject
{
    public string EmailAddress { get; set; }
    public string SkuNumber { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

希望这有助于解决问题。

答案 1 :(得分:0)

将LINQToXML与明智地使用xpath相结合,可能在您的投影中。我不记得确切的语法,但你的xpath会是这样的:

/Request/Item/value[../name={PropertyName}]

您可以将{FirstName'或“LastName”替换为{PropertyName}。

答案 2 :(得分:0)

如果您不想要XPath,可以将xml加载到XElement中然后获取项目,例如

var requestXml = XElement.Parse(@"<Request>       
    <EmailAddress>string</EmailAddress>
    <Item>
        <name>FirstName</name>
        <value>John</value>
    </Item>
    <Item>
        <name>LastName</name>
        <value>Doe</value>
    </Item>
</Request>");

var firstNameItem = (from i in requestXml.Elements("Item").Where(x=>x.Element("name").Value == "FirstName")).FirstOrDefault() ?? new XElement("Item", new XElement("value", ""));

var lastNameItem = (from i in requestXml.Elements("Item").Where(x=>x.Element("name").Value == "LastName")).FirstOrDefault() ?? new XElement("Item", new XElement("value", ""));

var firstName = firstNameItem.Element("value").Value;
var lastName = lastNameItem.Element("value").Value;

或类似的东西。

编辑:

如果您的xml看起来更像这样,那么您可以使用XmlSerializer在对象和xml之间来回切换。

<Request>
    <EmailAddress>value</EmailAddress>
    <SkuNumber>value</SkuNumber>
    <FirstName>value</FirstName>
    <LastName>value</LastName>
</Request>