在值中搜索字符串并在 LINQ 中获取属性值到 VB.NET 中的 XML
search string in value and get attribute value in LINQ to XML in VB.NET
我有一个 XML 文件,我想使用 Contains 命令搜索“val”的值并获取其“索引”属性以及“目录名称”属性。
<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
最简单的方法是对 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
和外部元素的 select 属性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 })
免责声明:我喜欢 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
输出:
index:1, name: n1
index:4, name: n2
它变得有点笨拙,因为您想要 n 对 m 关系中的 m 个项目(n 个目录和 m 个值),因此我们使用 SelectMany 将目录投影到多个值中。但是对象 list
拥有您可以用于其他目的的所有数据。
如另一个答案所述,您正在搜索包含“示例文本 1”但 returns“示例文本 10”的字符串,并且根据您想要的输出,您应该搜索完全匹配。
我有一个 XML 文件,我想使用 Contains 命令搜索“val”的值并获取其“索引”属性以及“目录名称”属性。
<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
最简单的方法是对 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
和外部元素的 select 属性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 })
免责声明:我喜欢 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
输出:
index:1, name: n1
index:4, name: n2
它变得有点笨拙,因为您想要 n 对 m 关系中的 m 个项目(n 个目录和 m 个值),因此我们使用 SelectMany 将目录投影到多个值中。但是对象 list
拥有您可以用于其他目的的所有数据。
如另一个答案所述,您正在搜索包含“示例文本 1”但 returns“示例文本 10”的字符串,并且根据您想要的输出,您应该搜索完全匹配。