在值中搜索字符串并在 VB.NET 中的 LINQ to XML 中获取属性值
Posted
技术标签:
【中文标题】在值中搜索字符串并在 VB.NET 中的 LINQ to XML 中获取属性值【英文标题】:search string in value and get attribute value in LINQ to XML in VB.NET 【发布时间】:2021-12-28 06:59:26 【问题描述】:我有一个 XML 文件,我想使用 Contains 命令搜索“val”的值并获取它的“index”属性以及“catalog name”属性。
<list>
<catalog index="1" name="n1">
<val index="1">sample text 1</val>
<val index="2">sample text 2</val>
<val index="3">sample text 3</val>
</catalog>
<catalog index="2" name="n2">
<val index="1">sample text 0</val>
<val index="2">sample text 2</val>
<val index="3">sample text 3</val>
<val index="4">sample text 1</val>
<val index="5">sample text 5</val>
<val index="6">sample text 6</val>
</catalog>
<catalog index="3" name="n3">
<val index="1">sample text 8</val>
<val index="2">sample text 9</val>
<val index="3">sample text 10</val>
</catalog>
</list>
我用过
Dim xml_Doc = XDocument.Load(myPath & "list.Xml")
Dim search_result As IEnumerable(Of XElement)
search_result =
(From c In xml_Doc.Descendants("catalog")
Where c.Elements("val").Value.Contains("sample text 1")
Select c.Elements("val").Attributes("index").ToString & c.Attribute("name").Value)
我该怎么做?
输出应该如下:
index:1 , name: n1
index:4 , name: n2
【问题讨论】:
【参考方案1】:免责声明:我喜欢 XmlSerialization。强类型和可重用的对象。我会首先通过创建一些类来将文件序列化为
来解决这个问题Imports System.IO
Imports System.Xml.Serialization
<XmlRoot("list")>
Public Class List
<XmlElement("catalog")>
Public Property Catalogs As List(Of Catalog)
End Class
Public Class Catalog
<XmlElement("val")>
Public Property Vals As List(Of Val)
<XmlAttribute("index")>
Public Property Index As Integer
<XmlAttribute("name")>
Public Property Name As String
End Class
Public Class Val
<XmlAttribute("index")>
Public Property Index As Integer
<XmlText>
Public Property Text As String
End Class
然后反序列化文件
Dim list As List
Dim serializer As New XmlSerializer(GetType(List))
Using sr As New StreamReader("list.xml")
list = CType(serializer.Deserialize(sr), List)
End Using
现在您的 xml 位于 .NET 类中,您可以使用 LINQ 来获取您想要的内容
Dim searchString = "sample text 1"
Dim catalogs As New List(Of Catalog)()
For Each catalog In list.Catalogs
Dim vals = catalog.Vals.Where(Function(val) val.Text = searchString)
For Each val In vals
catalogs.Add(New Catalog() With .Vals = val.ToList(), .Name = catalog.Name, .Index = catalog.Index)
Next
Next
Dim search_results = catalogs.SelectMany(Function(c) c.Vals.Select(Function(v) $"index:v.Index, name: c.Name"))
For Each search_result In search_results
Console.WriteLine(search_result)
Next
输出:
索引:1,名称:n1 索引:4,名称:n2
它有点笨拙,因为您希望 m 个项目来自 n 到 m 的关系(n 个目录和 m 个 val),因此我们使用 SelectMany 将目录投影到 val 的数量中。但是list
对象拥有您可以使用的所有数据。
如另一个答案中所述,您正在搜索包含“示例文本 1”但返回“示例文本 10”的字符串,并且根据您想要的输出,您应该搜索完全匹配。 em>
【讨论】:
【参考方案2】:最简单的方法是在c.Elements("val")
元素上嵌套From
查询,如下所示:
Dim sampleText = "sample text 1"
Dim search_result =
(From c In xml_Doc.Descendants("catalog")
From v in c.Elements("val")
Where v.Value.Contains(sampleText)
Select New With .index = v.Attribute("index").Value, .name = c.Attribute("name").Value )
For Each s In search_result
Console.WriteLine("index:0 , name:1", s.index, s.name)
Next
产生:
index:1 , name:n1
index:4 , name:n2
index:3 , name:n3
注意事项:
这样做可以让您轻松过滤内部元素v
的值,然后从v
和外部元素c
中选择属性。
index:3 , name:n3
包含在结果中,因为此元素的文本 sample text 10
包含搜索字符串 sample text 1
。如果您不希望包含此元素,请将您的 Where
子句更改为使用相等:
Dim search_result =
(From c In xml_Doc.Descendants("catalog")
From v in c.Elements("val")
Where v.Value = sampleText
Select New With .index = v.Attribute("index").Value, .name = c.Attribute("name").Value )
演示小提琴here 和here。
【讨论】:
谢谢。它工作正常。但第二个答案更有原则。以上是关于在值中搜索字符串并在 VB.NET 中的 LINQ to XML 中获取属性值的主要内容,如果未能解决你的问题,请参考以下文章