VB解析XML与几个孩子我如何确保我捕获所有的值



我正在努力读取XML文件,捕获其元素,进行任何转换/计算,需要为该特定文件完成,然后上传到SQL DB。现在我只需要帮助,我将如何解析和保持所有的xml数据,以便我可以把它放在哪里。对于如何使用这种格式的XML,我一直感到困惑。我通常可以得到PList, Name, Desc值,但不是任何值,我要找的是这样的东西:

输出如:列表,名称,名称,代码,价格。其中Plist, Name, Desc将保持不变,直到找到下一个,依此类推。

示例XML

<?xml version="1.0" encoding="iso-8859-1" ?>
<CoatSchedules>
<Cot PList="02" Name="CDC" Desc="PAR/PAV/EX3/RCH/EXP">
<Color Code="ARC" Price="39.58"/>
<Color Code="BAR" Price="39.58" **Default="50.00"**/>
<Color Code="BEP" Price="58.54"/>
<Color Code="BEX" Price="51.54"/>
</Cot>
<Cot PList="0A" Name="E6C" Desc="PAR/PAV" **Deduct="2.00"**>
<Color Code="BPA" Price="24.00"/>
<Color Code="BPV" Price="24.00"/>
<Color Code="COT" Price="0.00"/>
<Color Code="PAR" Price="24.00"/>
<Color Code="PAV" Price="24.00"/>
<Color Code="UTP" Price="25.00"/>
<Color Code="UTV" Price="20.00"/>
<Color Code="UV" Price="6.72"/>
</Cot>
</CoatSchedules>

编辑:默认和扣除都添加到显示"未知";项目不期望,但我们要注意,我们看到它在文件中我已经尝试过XDocument,但我认为这可能需要使用XmlReader,因为这些文件可能非常大,我读到阅读器更适合于此。

For Each element As XElement In xd.Root.Elements("Cot")
Console.WriteLine("PList: {0}; Name: {1}; Desc:{2}; Code: {3}; Price: {4}", CStr(element.Element("PList").Value), CStr(element.Element("Name")), CStr(element.Element("Desc")), CStr(element.Element("Code")), CStr(element.Element("Price")))
Dim PListValue = element.Attribute("PList").Value
Dim NameValue = element.Attribute("Name").Value
Dim DescriptionValue = element.Attribute("Desc").Value
Dim ColorCodeValue
Dim PriceValue
Console.WriteLine("PList: {0}; Name: {1}; Desc:{2};", PListValue, NameValue, DescriptionValue)
For Each child As XElement In element.Elements("Color")
Dim ColorCodeValue = child.Attribute("Code").Value
Dim PriceValue = child.Attribute("Price").Value
Console.WriteLine(" Code: {0}; Price: {1}", ColorCodeValue, PriceValue)
Next
Next

我如何捕获这些元素/属性值到只是变量,现在,我可以操纵和/或发送到需要的SQL数据库?

EDIT2:这里是我需要读取的大型XML的一个小样本,从我可以看出,我需要使用XMLReader,甚至可能使用LINQ来从这个大文件中获取所有数据。举个例子,我也很感激你们太棒了!

<?xml version="1.0" encoding="iso-8859-1" ?>
<Styles>
<Material PList="02" Code="B53">
<Style Name="ARRAY *" Fin="S" Sph="92.70" POW="012" PRS="001" BCV="002"
COL="CLR" TNT="002" COT="R8C" EDG="602" FRM="001"/>
<Style Name="ARRAY 2 *" Fin="S" Sph="92.70" POW="012" PRS="001" BCV="002"
COL="CLR" TNT="002" COT="R8C" EDG="602" FRM="001"/>
<Style Name="ARRAY 2 W *" Fin="S" Sph="92.70" POW="012" PRS="001" BCV="002"
COL="CLR" TNT="002" COT="R8C" EDG="602" FRM="001"/>
<Style Name="ARRAY W *" Fin="S" Sph="92.70" POW="012" PRS="001" BCV="002"
COL="CLR" TNT="002" COT="R8C" EDG="602" FRM="001"/>
</Material>
<Material PList="02" Code="B67">
<Style Name="ARRAY *" Fin="S" Sph="92.70" POW="013" PRS="001" BCV="002"
COL="CLR" TNT="002" COT="R8C" EDG="604" FRM="001"/>
<Style Name="ARRAY 2 *" Fin="S" Sph="92.70" POW="013" PRS="001" BCV="002"
COL="CLR" TNT="002" COT="R8C" EDG="604" FRM="001"/>
<Style Name="ARRAY 2 W *" Fin="S" Sph="92.70" POW="013" PRS="001" BCV="002"
COL="CLR" TNT="002" COT="R8C" EDG="604" FRM="001"/>
<Style Name="ARRAY W *" Fin="S" Sph="92.70" POW="013" PRS="001" BCV="002"
COL="CLR" TNT="002" COT="R8C" EDG="604" FRM="001"/>
</Material>
.
.
.
</Material>
</Styles>

尝试以下

Imports System.Xml
Imports System.Xml.Linq
Module Module1
Const FILENAME As String = "c:temptest.xml"
Sub Main()
Dim reader As XmlReader = XmlReader.Create(FILENAME)
While (Not reader.EOF)
If (reader.Name <> "Material") Then
reader.ReadToFollowing("Material")
End If
If (Not reader.EOF) Then
Dim material As XElement = XElement.ReadFrom(reader)
Dim plist As String = material.Attribute("PList").Value
Dim code As String = material.Attribute("Code").Value
Console.WriteLine("Material = {0}, Code = {1}", plist, code)
End If
End While
Console.ReadLine()
End Sub
End Module

我想,您可以,应该使用XElement

Dim xe As XElement
' xe = XElement.Load("path here")
' for testing use literal
xe = <CoatSchedules>
<Cot PList="02" Name="CDC" Desc="PAR/PAV/EX3/RCH/EXP">
<Color Code="ARC" Price="39.58"/>
<Color Code="BAR" Price="39.58"/>
<Color Code="BEP" Price="58.54"/>
<Color Code="BEX" Price="51.54"/>
</Cot>
<Cot PList="0A" Name="E6C" Desc="PAR/PAV">
<Color Code="BPA" Price="24.00"/>
<Color Code="BPV" Price="24.00"/>
<Color Code="COT" Price="0.00"/>
<Color Code="PAR" Price="24.00"/>
<Color Code="PAV" Price="24.00"/>
<Color Code="UTP" Price="25.00"/>
<Color Code="UTV" Price="20.00"/>
<Color Code="UV" Price="6.72"/>
</Cot>
</CoatSchedules>
Dim errs As String = VerifyXML(xe) ' <<<<<< One change  <<<<<<<
For Each cot As XElement In xe.<Cot>
Dim PListValue As String = cot.@PList
Dim NameValue As String = cot.@Name
Dim DescriptionValue As String = cot.@Desc
For Each clr As XElement In cot.<Color>
Dim ColorCodeValue As String = clr.@Code
Dim PriceValue As String = clr.@Price
Stop ' for debug
Next
Next

编辑:

验证XML。查看上面代码的一个更改

Private Function VerifyXML(someXML As XElement) As String
Dim sb As New System.Text.StringBuilder
Dim attrs As List(Of XAttribute) = someXML.Attributes.ToList
Select Case someXML.Name.LocalName
Case "CoatSchedules"
Case "Cot"
' PList="" Name="" Desc=""
For Each attr As XAttribute In attrs
Select Case attr.Name
Case "PList", "Name", "Desc"
Case Else
sb.AppendFormat("Cot unknown attribute {0}", attr.Name)
sb.AppendLine()
End Select
Next
Case "Color"
' Code="" Price=""
For Each attr As XAttribute In attrs
Select Case attr.Name
Case "Code", "Price"
Case Else
sb.AppendFormat("Color unknown attribute {0}", attr.Name)
sb.AppendLine()
End Select
Next
Case Else
sb.AppendFormat("Unknown element {0}", someXML.Name.LocalName)
sb.AppendLine()
End Select
For Each el As XElement In someXML.Elements
sb.Append(VerifyXML(el))
Next
Return sb.ToString
End Function

对不起,我没有代码可以分享。

我过去的方法是将XML文档预解析为键值对,其中键是节点的XPATH地址,值是节点的内容(如果有的话)。我想我使用了递归算法通过遍历System.Xml.XmlNode子节点来构建XPATH。

这允许基于XPATH的简单线性解析算法,并且可以处理无法识别的节点。

最新更新