从 XML 文件中检索某些数据
Retrieve certain data from XML File
我的 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<DisksLibrary>
<Disk>
<DiskName>Test</DiskName>
<DiskPath>testpath</DiskPath>
</Disk>
<Disk>
<DiskName>Test1</DiskName>
<DiskPath>testpath1</DiskPath>
</Disk>
<Disk>
<DiskName>Test2</DiskName>
<DiskPath>testpath2</DiskPath>
</Disk>
</DisksLibrary>
我想知道,因为我有多个同名标签,例如在我的 XML 文件中,是否可以从 XML 文件中检索一组特定的数据?例如,如果我想检索与 InnerText 为 "Test" 的同一组下的 DiskPath innertext。换句话说,我应该检索的 DiskPath 是 "testpath1"。我如何确保它不会与其他 DiskPath 内部文本混淆?
我尝试在线搜索但没有提供解决方案或提供的解决方案不适合我。我找到了一种似乎可行的解决方案,但在阅读代码后我认为如果有多个同名标签则行不通。
我找到的解决方案,我不确定它是否解决了我的问题是:
Dim document As XmlReader = New XmlTextReader("MyXML.xml")
While (document.Read())
Dim type = document.NodeType
If (type = XmlNodeType.Element) Then
If (document.Name = "FirstName") Then
TextBox1.Text = document.ReadInnerXml.ToString()
End If
If (document.Name = "LastName") Then
TextBox2.Text = document.ReadInnerXml.ToString()
End If
End If
End While
感谢您的帮助。欣赏一下。
阅读有关 XPath 和 Predicates (http://www.w3schools.com/xpath/xpath_syntax.asp) 的文章将对您非常有用。在您的实例中,您想要 return 其兄弟 "DiskName" 的值为 "Test" 的任何 "DiskPath" 元素的内部文本。正如 Styxxy 所描述的那样,XPath /DisksLibrary/Disk[DiskName="Test"]/DiskPath
将实现这一点:
Dim doc As New XmlDocument
Dim targetPath As String
doc.Load("MyXML.xml")
Dim foundNode As XmlNode = doc.SelectSingleNode("/DisksLibrary/Disk[DiskName='Test']/DiskPath")
If Not (foundNode Is Nothing) Then
targetPath = foundNode.InnerText
End If
我会考虑参数化 XPath 方法以使其可扩展。
Imports System.Xml
Module Module1
Sub Main()
Dim xml As String = _
"<?xml version=""1.0"" encoding=""utf-8""?>" & _
"<DisksLibrary>" & _
" <Disk>" & _
" <DiskName>Test1</DiskName>" & _
" <DiskPath>testpath1</DiskPath>" & _
" </Disk>" & _
" <Disk>" & _
" <DiskName>Test2</DiskName>" & _
" <DiskPath>testpath2</DiskPath>" & _
" </Disk>" & _
" <Disk>" & _
" <DiskName>Test3</DiskName>" & _
" <DiskPath>testpath3</DiskPath>" & _
" </Disk>" & _
"</DisksLibrary>"
Dim doc As New XmlDocument
doc.LoadXml(xml)
For i = 1 To 4
Dim foundNode = FindSiblingNode(doc, "Test" & i, "DiskPath")
Console.WriteLine(If(Not foundNode Is Nothing, foundNode.InnerText, "Node not found"))
Next
Console.ReadLine()
End Sub
Public Function FindSiblingNode(ByVal doc As XmlDocument, _
ByVal siblingNodeInnerText As String, _
ByVal searchNodeName As String) As XmlNode
Return doc.SelectSingleNode(String.Format("/DisksLibrary/Disk[DiskName='{0}']/{1}", siblingNodeInnerText, searchNodeName))
End Function
End Module
结果:
testpath1
testpath2
testpath3
Node not found
这是另一个使用 LINQ to XML 和 XML 文字的选项:
Dim document = XDocument.Load("MyXML.xml")
Dim path As String = (
From disk In document...<Disk>
Where disk.<DiskName>.Value = "Test"
Select disk.<DiskPath>.Value
).SingleOrDefault()
path
将是匹配的 <DiskPath>
元素的值,如果未找到,则为 Nothing
。
我的 XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<DisksLibrary>
<Disk>
<DiskName>Test</DiskName>
<DiskPath>testpath</DiskPath>
</Disk>
<Disk>
<DiskName>Test1</DiskName>
<DiskPath>testpath1</DiskPath>
</Disk>
<Disk>
<DiskName>Test2</DiskName>
<DiskPath>testpath2</DiskPath>
</Disk>
</DisksLibrary>
我想知道,因为我有多个同名标签,例如在我的 XML 文件中,是否可以从 XML 文件中检索一组特定的数据?例如,如果我想检索与 InnerText 为 "Test" 的同一组下的 DiskPath innertext。换句话说,我应该检索的 DiskPath 是 "testpath1"。我如何确保它不会与其他 DiskPath 内部文本混淆?
我尝试在线搜索但没有提供解决方案或提供的解决方案不适合我。我找到了一种似乎可行的解决方案,但在阅读代码后我认为如果有多个同名标签则行不通。
我找到的解决方案,我不确定它是否解决了我的问题是:
Dim document As XmlReader = New XmlTextReader("MyXML.xml")
While (document.Read())
Dim type = document.NodeType
If (type = XmlNodeType.Element) Then
If (document.Name = "FirstName") Then
TextBox1.Text = document.ReadInnerXml.ToString()
End If
If (document.Name = "LastName") Then
TextBox2.Text = document.ReadInnerXml.ToString()
End If
End If
End While
感谢您的帮助。欣赏一下。
阅读有关 XPath 和 Predicates (http://www.w3schools.com/xpath/xpath_syntax.asp) 的文章将对您非常有用。在您的实例中,您想要 return 其兄弟 "DiskName" 的值为 "Test" 的任何 "DiskPath" 元素的内部文本。正如 Styxxy 所描述的那样,XPath /DisksLibrary/Disk[DiskName="Test"]/DiskPath
将实现这一点:
Dim doc As New XmlDocument
Dim targetPath As String
doc.Load("MyXML.xml")
Dim foundNode As XmlNode = doc.SelectSingleNode("/DisksLibrary/Disk[DiskName='Test']/DiskPath")
If Not (foundNode Is Nothing) Then
targetPath = foundNode.InnerText
End If
我会考虑参数化 XPath 方法以使其可扩展。
Imports System.Xml
Module Module1
Sub Main()
Dim xml As String = _
"<?xml version=""1.0"" encoding=""utf-8""?>" & _
"<DisksLibrary>" & _
" <Disk>" & _
" <DiskName>Test1</DiskName>" & _
" <DiskPath>testpath1</DiskPath>" & _
" </Disk>" & _
" <Disk>" & _
" <DiskName>Test2</DiskName>" & _
" <DiskPath>testpath2</DiskPath>" & _
" </Disk>" & _
" <Disk>" & _
" <DiskName>Test3</DiskName>" & _
" <DiskPath>testpath3</DiskPath>" & _
" </Disk>" & _
"</DisksLibrary>"
Dim doc As New XmlDocument
doc.LoadXml(xml)
For i = 1 To 4
Dim foundNode = FindSiblingNode(doc, "Test" & i, "DiskPath")
Console.WriteLine(If(Not foundNode Is Nothing, foundNode.InnerText, "Node not found"))
Next
Console.ReadLine()
End Sub
Public Function FindSiblingNode(ByVal doc As XmlDocument, _
ByVal siblingNodeInnerText As String, _
ByVal searchNodeName As String) As XmlNode
Return doc.SelectSingleNode(String.Format("/DisksLibrary/Disk[DiskName='{0}']/{1}", siblingNodeInnerText, searchNodeName))
End Function
End Module
结果:
testpath1
testpath2
testpath3
Node not found
这是另一个使用 LINQ to XML 和 XML 文字的选项:
Dim document = XDocument.Load("MyXML.xml")
Dim path As String = (
From disk In document...<Disk>
Where disk.<DiskName>.Value = "Test"
Select disk.<DiskPath>.Value
).SingleOrDefault()
path
将是匹配的 <DiskPath>
元素的值,如果未找到,则为 Nothing
。