为一个非常初学的问题道歉;我非常擅长将VB与XML结合使用,并需要一些指导才能达到一定的理解力。
给出以下描述各种糖果的XML:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<Candy ID="MnMs">
<Form ID="tablet" Name="Tablet">
<Component ID="shell" Ingredients="sugar"/>
<Component ID="filling" Ingredients="chocolate"/>
</Form>
<Form ID="oblong">
<Component ID="shell" Ingredients="sugar"/>
<Component ID="filling" Ingredients="chocolate"/>
<Component ID="center" Ingredients="nut"/>
</Form>
</Candy>
<Candy ID="LBalls">
<Form ID="sphere">
<Component ID="shell" Ingredients="chocolate"/>
<Component ID="filling" Ingredients="chocolate ganache"/>
</Form>
</Candy>
<Candy ID="RPieces">
<Form ID="tablet">
<Component ID="shell" Ingredients="sugar"/>
<Component ID="filling" Ingredients="peanut butter ganache"/>
</Form>
</Candy>
</xs:schema>
(注意使用ID
而不是更典型的(推荐?)id
。)
如何在VB中访问Ingredients
RPieces / tablet / filling的<Component>
属性?具体来说,这一行:
<Component ID="filling" Ingredients="peanut butter ganache"/>
我的VB功能如下;我对如何管理身份感到困惑,特别是考虑到属性为ID
与id
。
Imports System.IO
Imports System.Xml
...
Function CandyFetch(ByVal candyId As String, ByVal formId As String, ByVal compId As String, ByVal attrId As String, Optional ByVal docPath As String = "Candies.xml") As String
Const ID = "ID"
Dim result = ""
docPath = docPath.Trim()
If Not File.Exists(docPath) Then docPath = AppDomain.CurrentDomain.BaseDirectory + docPath
For Each bonbon In XElement.Load(docPath).Elements("Candy")
If bonbon.Attribute(ID).Value = candyId Then
For Each form In bonbon.Elements("Form")
If form.Attribute(ID).Value = formId Then
For Each component In form.Elements("Component")
If component.Attribute(ID).Value = compId Then
result = component.Attribute(attrId).Value
Exit For
End If
Next
End If
Next
End If
Next
Return result
End Function
谢谢。
打桩,有没有更简单的方法使用LinqToXml来完成这个,而不必迭代XML元素?
答案 0 :(得分:1)
我建议使用XPATH查询:
Dim filename As String = "C:\Junk\example.xml"
Dim xdc As New XmlDocument
xdc.Load(filename)
Dim nsm As New XmlNamespaceManager(xdc.NameTable)
nsm.AddNamespace("xs", "http://www.w3.org/2001/XMLSchema")
Dim strXPATH As String = "/xs:schema/Candy[@ID=""RPieces""]/Form/Component[@ID=""filling""]/@Ingredients"
MsgBox(strXPATH & "=" & vbCrLf &
xdc.DocumentElement.SelectSingleNode(strXPATH, nsm).InnerText)
答案 1 :(得分:1)
使用LINQ to Xml,它可以如下所示
Dim doc As XDocument = XDocument.Load(docPath)
Dim value = doc.Descendants("Candy").
Where(Function(candy) candy.Attribute("ID").Value = "RPieces").
SelectMany(Function(candy) candy.Elements("Form")).
Where(Function(form) form.Attribute("ID").Value = "tablet").
SelectMany(Function(form) form.Elements("Component")).
Where(Function(component) component.Attribute("ID").Value = "filling").
Select(Function(component) component.Attribute("Ingredients").Value).
FirstOrDefault()
通过使用具有Xml Axis属性的LINQ to Xml,您可以简化代码投标 XML Attribute Axis Property (Visual Basic)
Dim doc As XDocument = XDocument.Load(docPath)
Dim value = doc...<Candy>.
Where(Function(candy) candy.@<ID> = "RPieces").
<Form>.
Where(Function(form) form.@<ID> = "tablet").
<Component>.
Where(Function(component) component.@<ID> = "filling").
Select(Function(component) component.@<Ingredients>).
FirstOrDefault()
如果您将命名空间导入代码,您将获得Intellisense帮助以编写轴属性的elments / attirbutes名称
另一种方法是使用序列化,创建表示xml结构的类,然后你的代码将如下所示
Dim serializer As New XmlSerializer(GetType(YourRootClass))
Dim data As YourRootClass = Nothing
Using fileStream As New FileStream(docPath, FileMode.Open)
data = serializer.Deserialize(fileStream)
End Using
Dim value = data.Candies.
Where(Function(candy) candy.ID = "RPieces").
SelectMany(Function(candy) candy.Forms).
Where(Function(form) form.ID = "tablet").
SelectMany(Function(form) form.Components).
Where(Function(component) component.ID = "filling").
Select(Function(component) component.Ingredients).
FirstOrDefault()