我已经搜索过,但似乎无法根据 c# 中同级 xml 元素的属性获取 xml 元素的属性
I've searched and I cannot seem to get the attribute of an xml element based on the attribute of a sibling xml element in c#
这是我的示例 xml:
<customers group="A">
<customer ID="1234" phone="555-555-0123" name="Golf Clubs International">
<services>
<service type="Golf" premise="89645" priority="0" />
</services>
<customFields>
<customField key="address" value="5431 E Golf Way, Altanta, GA, 31111" />
<customField key="connection" value="CONNECTED" />
</customFields>
</customer>
我需要 return 服务等于 89645 的 customField 地址值。我尝试了几种使用 XElement 的不同方法,但 none 似乎过滤了我需要的内容,甚至在我得到它进行过滤,我不知道如何重新导航以获取同级元素的属性。以下是我尝试过滤前提属性的一些内容。我已经使用这个网站好几年了,这是我第一次被难倒 post 一个问题。
IEnumerable<XElement> tests =
from el in cust.Elements("services")
where (string)el.Elements("service").Attributes("premise").ToString() == ID
select el;
var y = cust.Element("customers")
.Elements("services")
.Where(b => b.Element("service").Value == ID)
.SingleOrDefault();
var x = from a in cust.Elements("service")
where a.Attribute("premise").Value == ID
select cust.Elements("customfields").Elements("customfield").Attributes("key");
我喜欢在这种情况下使用字典。请参阅下面的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication58
{
class Program
{
const string FILENAME = @"C:\TEMP\TEST.XML";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var query = doc.Descendants("customer").Select(x => new{
premise = (string)x.Descendants("service").FirstOrDefault().Attribute("premise"),
customFields = x.Descendants("customField").GroupBy(y => (string)y.Attribute("key"), z => (string)z.Attribute("value"))
.ToDictionary(y => y.Key, z => z.FirstOrDefault())
}).ToList();
var results = query.Where(x => x.premise == "89645").FirstOrDefault();
}
}
}
这是一个单语句解决方案
XDocument 文档 = XDocument.Load(文件名);
var query = doc.Descendants("customer").Select(x => new {
premise = (string)x.Descendants("service").FirstOrDefault().Attribute("premise"),
customFields = x.Descendants("customField").GroupBy(y => (string)y.Attribute("key"), z => (string)z.Attribute("value"))
.ToDictionary(y => y.Key, z => z.FirstOrDefault())
}).Where(x => x.premise == "89645")
.FirstOrDefault();
对于 VB 可能会找到这个的人。
首先是一些示例数据
Dim xe As XElement
xe = <customers group="A">
<customer ID="1234" phone="555-555-0123" name="Golf Clubs International">
<services>
<service type="Golf" premise="89645" priority="0"/>
</services>
<customFields>
<customField key="address" value="5431 E Golf Way, Altanta, GA, 31111"/>
<customField key="connection" value="CONNECTED"/>
</customFields>
</customer>
<customer ID="567" phone="555-555-0123" name="Golf Clubs International">
<services>
<service type="Golf" premise="54698" priority="0"/>
</services>
<customFields>
<customField key="address" value="5431 E Golf Way, Altanta, GA, 31111"/>
<customField key="connection" value="CONNECTED"/>
</customFields>
</customer>
<customer ID="890" phone="555-555-0123" name="Golf Clubs International">
<services>
<service type="Golf" premise="89645" priority="0"/>
</services>
<customFields>
<customField key="address" value="718 W. High, Jefferson City, MO 65101"/>
<customField key="connection" value="CONNECTED"/>
</customFields>
</customer>
</customers>
然后是获取地址的步骤
Dim rslts As IEnumerable(Of XElement)
'first get service equals 89645, using above there are two
rslts = From el In xe...<service>
Where el.@premise = "89645"
Select el
'for each of those find the address
For Each rel As XElement In rslts
Dim ie As IEnumerable(Of XElement)
ie = rel.Parent.Parent.<customFields>.<customField>.Where(Function(cfel)
Return cfel.@key = "address"
End Function)
For Each a As XElement In ie
Debug.WriteLine(a.@value)
Next
Next
查询可以缩短,但此代码用于说明正在发生的事情。
这是我的示例 xml:
<customers group="A">
<customer ID="1234" phone="555-555-0123" name="Golf Clubs International">
<services>
<service type="Golf" premise="89645" priority="0" />
</services>
<customFields>
<customField key="address" value="5431 E Golf Way, Altanta, GA, 31111" />
<customField key="connection" value="CONNECTED" />
</customFields>
</customer>
我需要 return 服务等于 89645 的 customField 地址值。我尝试了几种使用 XElement 的不同方法,但 none 似乎过滤了我需要的内容,甚至在我得到它进行过滤,我不知道如何重新导航以获取同级元素的属性。以下是我尝试过滤前提属性的一些内容。我已经使用这个网站好几年了,这是我第一次被难倒 post 一个问题。
IEnumerable<XElement> tests =
from el in cust.Elements("services")
where (string)el.Elements("service").Attributes("premise").ToString() == ID
select el;
var y = cust.Element("customers")
.Elements("services")
.Where(b => b.Element("service").Value == ID)
.SingleOrDefault();
var x = from a in cust.Elements("service")
where a.Attribute("premise").Value == ID
select cust.Elements("customfields").Elements("customfield").Attributes("key");
我喜欢在这种情况下使用字典。请参阅下面的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication58
{
class Program
{
const string FILENAME = @"C:\TEMP\TEST.XML";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var query = doc.Descendants("customer").Select(x => new{
premise = (string)x.Descendants("service").FirstOrDefault().Attribute("premise"),
customFields = x.Descendants("customField").GroupBy(y => (string)y.Attribute("key"), z => (string)z.Attribute("value"))
.ToDictionary(y => y.Key, z => z.FirstOrDefault())
}).ToList();
var results = query.Where(x => x.premise == "89645").FirstOrDefault();
}
}
}
这是一个单语句解决方案
XDocument 文档 = XDocument.Load(文件名);
var query = doc.Descendants("customer").Select(x => new {
premise = (string)x.Descendants("service").FirstOrDefault().Attribute("premise"),
customFields = x.Descendants("customField").GroupBy(y => (string)y.Attribute("key"), z => (string)z.Attribute("value"))
.ToDictionary(y => y.Key, z => z.FirstOrDefault())
}).Where(x => x.premise == "89645")
.FirstOrDefault();
对于 VB 可能会找到这个的人。
首先是一些示例数据
Dim xe As XElement
xe = <customers group="A">
<customer ID="1234" phone="555-555-0123" name="Golf Clubs International">
<services>
<service type="Golf" premise="89645" priority="0"/>
</services>
<customFields>
<customField key="address" value="5431 E Golf Way, Altanta, GA, 31111"/>
<customField key="connection" value="CONNECTED"/>
</customFields>
</customer>
<customer ID="567" phone="555-555-0123" name="Golf Clubs International">
<services>
<service type="Golf" premise="54698" priority="0"/>
</services>
<customFields>
<customField key="address" value="5431 E Golf Way, Altanta, GA, 31111"/>
<customField key="connection" value="CONNECTED"/>
</customFields>
</customer>
<customer ID="890" phone="555-555-0123" name="Golf Clubs International">
<services>
<service type="Golf" premise="89645" priority="0"/>
</services>
<customFields>
<customField key="address" value="718 W. High, Jefferson City, MO 65101"/>
<customField key="connection" value="CONNECTED"/>
</customFields>
</customer>
</customers>
然后是获取地址的步骤
Dim rslts As IEnumerable(Of XElement)
'first get service equals 89645, using above there are two
rslts = From el In xe...<service>
Where el.@premise = "89645"
Select el
'for each of those find the address
For Each rel As XElement In rslts
Dim ie As IEnumerable(Of XElement)
ie = rel.Parent.Parent.<customFields>.<customField>.Where(Function(cfel)
Return cfel.@key = "address"
End Function)
For Each a As XElement In ie
Debug.WriteLine(a.@value)
Next
Next
查询可以缩短,但此代码用于说明正在发生的事情。