C# 如何从XDocument中的一个节点获取一个元素,其中还有两个其他元素是已知的

C# 如何从XDocument中的一个节点获取一个元素,其中还有两个其他元素是已知的,c#,.net-3.5,elements,linq-to-xml,C#,.net 3.5,Elements,Linq To Xml,我(再次)被对XDocument/Linq的误解难住了。对于下面的XML,我将nameEn和provinceCode作为代码中的变量。我试图识别code(例如,s0000002)和nameFr,因为我有另外两个元素。provinceCode和NameEn组合在XML中是唯一的(无重复) 埃德蒙顿 埃德蒙顿 AB 阿尔冈金公园 阿尔冈金公园 在…上 ... 以下是我正在尝试的代码(我的XML在“已加载”的XDocument中: selectedProvince = "ON"; selected

我(再次)被对XDocument/Linq的误解难住了。对于下面的XML,我将
nameEn
provinceCode
作为代码中的变量。我试图识别
code
(例如,
s0000002
)和
nameFr
,因为我有另外两个元素。
provinceCode
NameEn
组合在XML中是唯一的(无重复)


埃德蒙顿
埃德蒙顿
AB
阿尔冈金公园
阿尔冈金公园
在…上
...
以下是我正在尝试的代码(我的XML在“已加载”的XDocument中:

selectedProvince = "ON";
selectedCity = "Algonquin Park";      
strSiteCode = loaded.Descendants("site")
    .Where(x => x.Element("provinceCode").Value == selectedProvince)
    .Where(x => x.Element("nameEn").Value == selectedCity)
    .Select(x => x.Element("code").Value)
    .ToString();
strNameFR = loaded.Descendants("site")
    .Where(x => x.Element("provinceCode").Value == selectedProvince)
    .Where (x => x.Element("nameEn").Value == selectedCity)
    .Select(x => x.Element("nameFr").Value)
    .ToString();
字符串
strSiteCode
返回:
System.Linq.Enumerable+whereselectEnumerableInterator
2[System.Xml.Linq.XElement,System.string]
strNameFR
返回

我不知道工作代码应该是什么样子。谢谢你的帮助

道格

试试看

var result = loaded.Descendants("site")
    .Where(x => (x.Element("provinceCode").Value == selectedProvince) &&
                 (x.Element("nameEn").Value == selectedCity) )
    .Select(x => x.Element("code").Value)
    .SingleOrDefault();

if (result != null)
{
    strSiteCode = result.ToString();
}

Select()
调用返回一个集合(在您的情况下,该集合恰好只有一个元素)。因此您必须调用
SingleOrDefault()
(或
Single()
)来获取一个项。此外,我删除了第二个
Where()
,并将条件包含到第一个
Where()

我可能会这样重写它:

// determine the matching list of <site> nodes ...
var selectedSites = loaded
                       .Descendants("site")
                       .Where(x => x.Element("provinceCode").Value == selectedProvince)
                       .Where(x => x.Element("nameEn").Value == selectedCity);

// iterate over all matching <site> nodes
foreach (var site in selectedSites)
{
    // grab the code attribute and nameFr element from <site> node
    var siteCode = site.Attribute("code").Value;
    var nameFR = site.Element("nameFr").Value;
}
  • 一次获取匹配的
    节点列表
  • 迭代所有匹配项(通常只有一个)
  • 从这些匹配项中获取
    code
    属性
    nameFr
    元素
代码如下所示:

// determine the matching list of <site> nodes ...
var selectedSites = loaded
                       .Descendants("site")
                       .Where(x => x.Element("provinceCode").Value == selectedProvince)
                       .Where(x => x.Element("nameEn").Value == selectedCity);

// iterate over all matching <site> nodes
foreach (var site in selectedSites)
{
    // grab the code attribute and nameFr element from <site> node
    var siteCode = site.Attribute("code").Value;
    var nameFR = site.Element("nameFr").Value;
}
//确定节点的匹配列表。。。
var selectedSites=已加载
.后代(“现场”)
。其中(x=>x.Element(“provinceCode”)。值==selectedProvince)
其中(x=>x.Element(“nameEn”).Value==selectedCity);
//迭代所有匹配的节点
foreach(所选站点中的var站点)
{
//从节点获取代码属性和nameFr元素
var siteCode=site.Attribute(“code”).Value;
var nameFR=site.Element(“nameFR”).Value;
}

请记住,“x.Element(…)”方法可能返回null,从而访问“Value”它将导致空引用。这是假设您的xml可能不总是具有provinceCode或nameEn。如果存在,您将不会有问题,但无论如何,您不会希望在发布代码中放置可能的空引用ex。下面解决了空引用问题

var site = loaded
    .Descendants("site")
    .FirstOrDefault(x => (string)x.Element("provinceCode") == selectedProvince &&
                    x => (string)x.Element("nameEn") == selectedCity);    

if (site == null)
{
    return
}

var siteCode = (string)site.Attribute("code");
var nameFr = (string)site.Element("nameFr");

非常感谢。我最终得到的代码与我开始时的代码基本相同。你的代码与我的代码不同之处在于你使用了“属性”而不是“元素”。这就是为什么strSiteCode的代码不起作用的原因。(谢谢!!)而我的strNameFR的代码实际上起作用了,只是我在测试时意外地将其设置为“”。(Doh!拍额头)@道格:一个经典的野餐:椅子上的问题-而不是计算机上的问题:-)使用此代码可能会出现一些空引用问题,顺便说一句:)@xixonia:是的,显然-这是绝对假设节点上的“provinceCode”和“nameEn”始终存在(以及节点上的“code”属性和节点内的“nameFr”元素)-当然!我不是想展示如何完美地处理所有潜在的错误…对。我很兴奋,因为类的XNode集合上的显式操作符对于这样的事情来说真的很酷。使用'(string)x.Element(…)'与'x.Element(…).Value'相同,除非元素为null,否则它只会在转换时返回null。:)嗨,巴拉。我没法让它工作。我一直遇到这样的错误:“运算符'&&'不能应用于'bool'和'System.Xml.Linq.XElement'类型的操作数”Thanks@Doug啊!!在组合这两个
Where()
s时,我忽略了一些东西。现在修好了。