从一个语句中的Xml文档中选择多个值

时间:2014-01-22 21:29:30

标签: c# xml linq linq-to-xml

我正在尝试使用

同时从两个相邻的xml节点中选择值
var values =
            xDoc.Element("root")
                .Elements("model")
                .Where(x => x.Element("modelName").Value == modelType.ToString())
                .Elements("directory")
                .Select(x => new { x.Element("directoryName").Value,
                               x.Element("taskName").Value });

我在.Value下面写着“复制匿名类型属性名称'值'时出现红色曲线。 这是xml

    <root>
  <model>
    <modelName>Model1</modelName>
    <directory>
      <directoryName>Dir1</directoryName>
      <taskName>Task1</taskName>
    </directory>
  </model>
  <model>
    <modelName>Model2</modelName>
    <directory>
      <directoryName>FirstValue</directoryName>
      <taskName>SecondValue</taskName>
    </directory>
  </model>
</root>

我想提取Dir1和Task1或FirstValue和SecondValue。

2 个答案:

答案 0 :(得分:3)

我建议您使用转换元素来字符串而不是访问它们的Value属性。因为如果缺少元素(例如,对于Model1,您没有taskName元素),那么您将获得NullReferenceException

var values = from m in xDoc.Root.Elements("model")
             where (string)m.Element("modelName") == modelType.ToString()
             let d = m.Element("directory")
             select new {
                Directory = (string)d.Element("directoryName"),
                Task = (string)d.Element("taskName")
             };

此外,我发现声明(查询)语法比lambda语法(品味问题)更具可读性。您还可以使用XPath使查询更紧凑:

string xpath = String.Format("root/model[modelName='{0}']/directory", modelType);
var values = from d in xdoc.XPathSelectElements(xpath)
             select new {
                 Directory = (string)d.Element("directoryName"),
                 Task = (string)d.Element("taskName")
             };

答案 1 :(得分:2)

想出来,你只需要在匿名类型中命名属性

var values =
            xDoc.Element("root")
                .Elements("model")
                .Where(x => x.Element("modelName").Value == modelType.ToString())
                .Elements("directory")
                .Select(x => new { Directory = x.Element("directoryName").Value,
                                   Task = x.Element("taskName").Value });