具有复杂过滤 LINQ to XML c# 的查询
Queries with complex filtering LINQ to XML c#
我想了解 LINQ 的复杂过滤 XML。
我创建了一个简单的 XML 示例 (DataBaseCities.xml):
<?xml version="1.0" encoding="utf-8"?>
<DataBase>
<DocumentInfo version="1.0" schemaVersion="1.0"/>
<ListOfMegaCities>
<MegaCities city="Moscow" continent="Europe">
<VariantConstraint>
<LanguageRef LanguageId="russian">
<LanguageDialectsRef DialectsId="north"/>
</LanguageRef>
</VariantConstraint>
<Districts>
<CityDistrict District="Arbat"/>
<CityDistrict District="Basmanny"/>
</Districts>
</MegaCities>
<MegaCities city="New York" continent="North America">
<VariantConstraint>
<LanguageRef LanguageId="english">
<LanguageDialectsRef DialectsId="west"/>
</LanguageRef>
<LanguageRef LanguageId="spanish">
<LanguageDialectsRef DialectsId="cental"/>
</LanguageRef>
</VariantConstraint>
<Districts>
<CityDistrict District="Queens"/>
<CityDistrict District="Bronx"/>
</Districts>
</MegaCities>
<MegaCities city="London" continent="Europe">
<VariantConstraint>
<LanguageRef LanguageId="english">
<LanguageDialectsRef DialectsId="west"/>
</LanguageRef>
<LanguageRef LanguageId="spanish">
<LanguageDialectsRef DialectsId="central"/>
</LanguageRef>
<LanguageRef LanguageId="french">
<LanguageDialectsRef DialectsId="central"/>
</LanguageRef>
</VariantConstraint>
<Districts>
<CityDistrict District="Greenwich"/>
<CityDistrict District="Westminster"/>
</Districts>
</MegaCities>
</ListOfMegaCities>
</DataBase>
我尝试像这样过滤:
XElement root = XElement.Load(@"DataBaseCities.xml");
IEnumerable<XElement> ListOfMegaCities =
from el in root.Descendants("MegaCities")
where
(from add in el.Descendants("LanguageRef")
where
(string)add.Attribute("LanguageId") == "english"
select add)
.Any()
select el;
foreach (XElement el in ListOfMegaCities)
{
Console.WriteLine((string)el.Attribute("city"));
}
所以输出是:
New York
London
但我想过滤不止一个属性。
如果我尝试使用这些行进行过滤:
(string)add.Attribute("LanguageId") == "英语" &&
(字符串)add.Attribute(“LanguageId”)==“西班牙语”
为什么它不起作用?
- 如何过滤“DialectsId”?
示例:我想通过以下过滤获得“纽约”:
LanguageId="english"
DialectsId="west"
LanguageId="spanish"
DialectsId="cental"
也许有人有复杂过滤的好资源?我找到了这个 https://docs.microsoft.com/de-de/dotnet/standard/linq/write-queries-complex-filtering 但这只对我有部分帮助...
首先,请参阅@zaggler 评论。反序列化和操作对象会更容易。
其次,如果您想要只说英语和西班牙语的城市,请参阅@AkshayGaonkar 的回答。如果您想要说英语和西班牙语(也许还有其他语言)的城市,请参阅我的回答。
为了写复杂的Linq查询,我开始写simulacrum SQL :
-- I want all cities
select * from MegaCities as el
where
-- that speak english with west dialect
exists (
select * from el.LanguageRef as add
where add.LanguageId = 'english' and
add.LanguageDialectsRef.DialectsId = 'west'
)
-- and also speak spanish with central dialect
and exists (
select * from el.LanguageRef as add
where add.LanguageId == 'spanish' and
add.LanguageDialectsRef.DialectsId = 'cental'
)
然后我可以转置到 Linq :
IEnumerable<XElement> ListOfMegaCities =
from el in root.Descendants("MegaCities")
where
(from add in el.Descendants("LanguageRef")
where add.Attribute("LanguageId").Value == "english" &&
add.Element("LanguageDialectsRef").Attribute("DialectsId").Value == "west"
select add)
.Any()
&&
(from add in el.Descendants("LanguageRef")
where add.Attribute("LanguageId").Value == "spanish" &&
add.Element("LanguageDialectsRef").Attribute("DialectsId").Value == "cental"
select add)
.Any()
select el;
也许不是最好的技巧,但有时会有所帮助。
我使用了All
而不是Any
,因此它只过滤那些满足所有条件的城市。我习惯于编写 LINQ 表达式而不是 LINQ 查询。
List<XElement> ListOfMegaCities = root.Descendants("MegaCities")
.Where(lr => lr.Descendants("LanguageRef")
.All(
li => (li.Attribute("LanguageId").Value == "english"
&& li.Element("LanguageDialectsRef").Attribute("DialectsId").Value == "west")
|| (li.Attribute("LanguageId").Value == "spanish"
&& li.Element("LanguageDialectsRef").Attribute("DialectsId").Value == "cental")
)
).ToList();
我想了解 LINQ 的复杂过滤 XML。 我创建了一个简单的 XML 示例 (DataBaseCities.xml):
<?xml version="1.0" encoding="utf-8"?>
<DataBase>
<DocumentInfo version="1.0" schemaVersion="1.0"/>
<ListOfMegaCities>
<MegaCities city="Moscow" continent="Europe">
<VariantConstraint>
<LanguageRef LanguageId="russian">
<LanguageDialectsRef DialectsId="north"/>
</LanguageRef>
</VariantConstraint>
<Districts>
<CityDistrict District="Arbat"/>
<CityDistrict District="Basmanny"/>
</Districts>
</MegaCities>
<MegaCities city="New York" continent="North America">
<VariantConstraint>
<LanguageRef LanguageId="english">
<LanguageDialectsRef DialectsId="west"/>
</LanguageRef>
<LanguageRef LanguageId="spanish">
<LanguageDialectsRef DialectsId="cental"/>
</LanguageRef>
</VariantConstraint>
<Districts>
<CityDistrict District="Queens"/>
<CityDistrict District="Bronx"/>
</Districts>
</MegaCities>
<MegaCities city="London" continent="Europe">
<VariantConstraint>
<LanguageRef LanguageId="english">
<LanguageDialectsRef DialectsId="west"/>
</LanguageRef>
<LanguageRef LanguageId="spanish">
<LanguageDialectsRef DialectsId="central"/>
</LanguageRef>
<LanguageRef LanguageId="french">
<LanguageDialectsRef DialectsId="central"/>
</LanguageRef>
</VariantConstraint>
<Districts>
<CityDistrict District="Greenwich"/>
<CityDistrict District="Westminster"/>
</Districts>
</MegaCities>
</ListOfMegaCities>
</DataBase>
我尝试像这样过滤:
XElement root = XElement.Load(@"DataBaseCities.xml");
IEnumerable<XElement> ListOfMegaCities =
from el in root.Descendants("MegaCities")
where
(from add in el.Descendants("LanguageRef")
where
(string)add.Attribute("LanguageId") == "english"
select add)
.Any()
select el;
foreach (XElement el in ListOfMegaCities)
{
Console.WriteLine((string)el.Attribute("city"));
}
所以输出是:
New York
London
但我想过滤不止一个属性。
如果我尝试使用这些行进行过滤:
(string)add.Attribute("LanguageId") == "英语" && (字符串)add.Attribute(“LanguageId”)==“西班牙语”
为什么它不起作用?
- 如何过滤“DialectsId”?
示例:我想通过以下过滤获得“纽约”:
LanguageId="english"
DialectsId="west"
LanguageId="spanish"
DialectsId="cental"
也许有人有复杂过滤的好资源?我找到了这个 https://docs.microsoft.com/de-de/dotnet/standard/linq/write-queries-complex-filtering 但这只对我有部分帮助...
首先,请参阅@zaggler 评论。反序列化和操作对象会更容易。
其次,如果您想要只说英语和西班牙语的城市,请参阅@AkshayGaonkar 的回答。如果您想要说英语和西班牙语(也许还有其他语言)的城市,请参阅我的回答。
为了写复杂的Linq查询,我开始写simulacrum SQL :
-- I want all cities
select * from MegaCities as el
where
-- that speak english with west dialect
exists (
select * from el.LanguageRef as add
where add.LanguageId = 'english' and
add.LanguageDialectsRef.DialectsId = 'west'
)
-- and also speak spanish with central dialect
and exists (
select * from el.LanguageRef as add
where add.LanguageId == 'spanish' and
add.LanguageDialectsRef.DialectsId = 'cental'
)
然后我可以转置到 Linq :
IEnumerable<XElement> ListOfMegaCities =
from el in root.Descendants("MegaCities")
where
(from add in el.Descendants("LanguageRef")
where add.Attribute("LanguageId").Value == "english" &&
add.Element("LanguageDialectsRef").Attribute("DialectsId").Value == "west"
select add)
.Any()
&&
(from add in el.Descendants("LanguageRef")
where add.Attribute("LanguageId").Value == "spanish" &&
add.Element("LanguageDialectsRef").Attribute("DialectsId").Value == "cental"
select add)
.Any()
select el;
也许不是最好的技巧,但有时会有所帮助。
我使用了All
而不是Any
,因此它只过滤那些满足所有条件的城市。我习惯于编写 LINQ 表达式而不是 LINQ 查询。
List<XElement> ListOfMegaCities = root.Descendants("MegaCities")
.Where(lr => lr.Descendants("LanguageRef")
.All(
li => (li.Attribute("LanguageId").Value == "english"
&& li.Element("LanguageDialectsRef").Attribute("DialectsId").Value == "west")
|| (li.Attribute("LanguageId").Value == "spanish"
&& li.Element("LanguageDialectsRef").Attribute("DialectsId").Value == "cental")
)
).ToList();