将XML内容加载到数据集 [英] Load XML-content to dataset
问题描述
需要一点帮助才能从XML-File创建数据集对象。文件内容是对服务器上的请求的响应,因此我无法控制XML-Structure 。文件内容(文件名TestProd5.xml)是:
<? xml version = 1.0 ? >
< ProductionOrder xmlns = http://www.sap.com/SBO/DIS >
< ; AbsoluteEntry > 17830 < / AbsoluteEntry & gt;
< ProductionOrderLine >
< LineNumber > 0 < / LineNumber >
< BatchNumbers / >
< / ProductionOrderLine < span class =code-keyword>>
< ProductionOrderLine >
< LineNumber > 1 < / LineNumber >
< span class =code-keyword>< BatchNumbers >
< BatchNumber >
< BatchNumber > 234 < span class =code-keyword>< / BatchNumber >
< 数量 > 1.000000 < span class =code-keyword>< / Quantity >
< BaseLineNumber > 1 < / BaseLineNumber >
< / BatchNumber >
< / BatchNumbers >
< / ProductionOrderLine >
< ProductionOrderLine >
< LineNumber > 2 < / LineNumber >
< BatchNumbers < span class =code-keyword>>
< BatchNumber >
< BatchNumber > 234 < / BatchNumber >
< 数量 > 2.000000 < / Quantity >
< BaseLineNumber > 2 < / BaseLineNumber >
< / BatchNumber >
< span class =code-keyword>< / BatchNumbers >
< / ProductionOrderLine >
< ProductionOrderLine >
< LineNumber > ; 3 < / LineNumber >
< BatchNumbers / >
< / ProductionOrderLine >
< / ProductionOrder >
我尝试过:
我尝试按以下方式加载数据:
Dim dsProd As DataSet = New DataSet()
dsProd.ReadXml(TestProd5.xml)
工作得很好,除了元素< BatchNumber> 234< / BatchNumber>
在数据集中被省略。因为我假设原因是具有相同名称的父元素。我在
dataset-object中需要这个值。我该怎么办?
欢迎任何帮助。
Manfred
使用以下方法加载XML数据的方法很少:
1) XML文档 [ ^ ]
2) XDocument [ ^ ]
3) XmlSerialization [ ^ ] => XML序列化示例Microsoft Docs [ ^ ]
正如我提到的预告片,您可以使用XDocument类将您的数据读入DataSet
对象。这是一个想法:
函数 LoadDataIntoDataSet() As DataSet
Dim xNamespace As XNamespace = http://www.sap.com/SBO/DIS
Dim xDoc As XDocument = XDocument.Parse(GetXmlData())
Dim ds As DataSet = 新 DataSet()
Dim pl As DataTable = 新 DataTable()
pl。 Columns.Add( New DataColumn( LineNumber,Type。 GetType ( System.Int32)))
Dim bn As DataTable = 新 DataTable()
bn.Columns.Add(新 DataColumn( LineNumber,类型。 GetType ( System.Int32)))
bn.Columns.Add( New DataColumn( BatchNumber ,键入。 GetType ( System。 Int32)))
bn.Columns.Add( New DataColumn( 数量,类型。 GetType ( System.String)))
bn.Columns.Add( New DataColumn(< span class =code-string> BaseLineNumber,类型。 GetType (< span class =code-string> System.Int32)))
对于 每个 pol 作为 XElement 在 xDoc.Descendants(xNamespace + ProductionOrderLine)
pl.Rows .Add( New Object (){pol.Element(xNamespace + LineNumber)。值})
对于 每个禁止作为 XElement 在 pol.Descendants(xNamespace + BatchNumber)。其中(< span class =code-keyword> Function (x)x.Descendants.Count> 0)
bn.Rows.Add( New 对象()_
{_
pol.Element(xNamespace + < span class =code-string> LineNumber)。值,_
ban.Element(xNamespace + BatchNumber)。值,_
ban.Element(xNamespace + 数量)。值,_
ban.Element(xNamespace + BaseLineNumber).Value _
})
下一步
下一步
ds.Tables.Add(pl)
ds.Tables.Add(bn)
返回 ds
结束 功能
但是,我强烈建议使用序列化(通过 DataContractSerializer Class(System.Runtime.Serialization)| Microsoft Docs [ ^ ])。在这种情况下,您需要一组类的定义:
' 需要参加System.Runtime.Serialization.dll
< DataContract([ Namespace ]:= http://www.sap.com/SBO/DIS)>
公开 类 ProductionOrder
< DataMember>
公共 AbsoluteEntry 作为 整数
< DataMember>
公共 ProductionOrderLines 作为列表( ProductionOrderLine)
结束 类
< DataContract>
公开 类 ProductionOrderLine
< DataMember>
公共 LineNumber 作为 整数
< DataMember>
公共 BatchNumbers 作为列表( Of BatchNumber)
结束 类
< DataContract>
公开 类 BatchNumber
< DataMember>
公共 BatchNumber 作为 整数
< DataMember>
公开数量作为 字符串
< DataMember>
公共 BaseLineNumber 作为 整数
结束 类
然后你就可以将xml数据转换成对象:
' 这个方法你只需要第一次!!!
Dim sFileName 作为 字符串 = FullFileName.xml
Dim xDoc As XDocument = XDocument。加载(sFileName)
Dim xns As XNamespace = http://www.sap.com/SBO/DIS
Dim po As ProductionOrder = 新 ProductionOrder()
po.AbsoluteEntry = xDoc.Root.Element(xns + AbsoluteEntry)。Value
po.ProductionOrderLines = 新列表( ProductionOrderLine)
For 每个 pol As XElement 在 xDoc.Descendants(xns + ProductionOrderLine)
< span class =code-keyword> Dim pl As ProductionOrderLine = 新 ProductionOrderLine()
pl.LineNumber = pol.Element(xns + LineNumber)。值
pl.BatchNumbers = 新列表( BatchNumber)
对于 每个禁止作为 XElement In pol.Descendants(xns + BatchNumber)。其中(函数(x)x.Descendants.Count> 0)
Dim bn 正如 BatchNumber = 新 BatchNumber()
使用 bn
.BatchNumber = ban.Element(xns + BatchNumber)。值
.Quantity = ban.Element(xns + Quantity)。值
.BaseLineNumber = ban.Element (xns + BaseLineNumber)。值
结束 使用
pl.BatchNumbers.Add(bn)
下一页
po.ProductionOrderLines.Add(pl)
下一步
' 现在你可以用正确的方式编写对象了:
WriteObject(sFileName,po)
' 再次阅读:
po = ReadObject(sFileName)
' gotcha!
阅读方法/ write object:
Sub WriteObject(_fileName 作为 字符串,po 作为 ProductionOrder)
使用 writer As FileStream = New FileStream(_fileName,FileMode.Create)
Dim knownTypes() AS 类型= 新类型(){ GetType (ProductionOrder), GetType (ProductionOrder), GetType (BatchNumber)}
Dim dcs As DataContractSerializer = 新 DataContractSerializer( GetType (ProductionOrder), knownTypes)
dcs.WriteObject(writer,po)
writer.Close()
结束 使用
结束 Sub
函数 ReadObject(_fileName As String )作为 ProductionOrder
Dim po 正如 ProductionOrder = 新 ProductionOrder()
使用 fs As FileStream = 新 FileStream(_fileName,FileMode.Open)
Dim reader As XmlDictionaryReader = XmlDictionaryReader.CreateTextReader(fs, New XmlDictionaryReaderQuotas( ))
Dim knownTypes() AS Type = 新类型(){ GetType (ProductionOrder), GetType (ProductionOrder), GetType (BatchNumber)}
Dim dcs As DataContractSerializer = 新 DataContractSerializer( GetType (ProductionOrder),knownTypes)
po = DirectCast (dcs.ReadObject(reader, True ) ,ProductionOrder)
reader.Close()
fs.Close()
结束 使用
返回 po
结束 函数
这是处理xml数据和自定义对象的方法!
Hi,
need a little help to create dataset-object from XML-File. File-content is a response to a request on a server, so I have no control on XML-Structure. Content of file (filename "TestProd5.xml") is:
<?xml version="1.0"?>
<ProductionOrder xmlns="http://www.sap.com/SBO/DIS">
<AbsoluteEntry>17830</AbsoluteEntry>
<ProductionOrderLine>
<LineNumber>0</LineNumber>
<BatchNumbers/>
</ProductionOrderLine>
<ProductionOrderLine>
<LineNumber>1</LineNumber>
<BatchNumbers>
<BatchNumber>
<BatchNumber>234</BatchNumber>
<Quantity>1.000000</Quantity>
<BaseLineNumber>1</BaseLineNumber>
</BatchNumber>
</BatchNumbers>
</ProductionOrderLine>
<ProductionOrderLine>
<LineNumber>2</LineNumber>
<BatchNumbers>
<BatchNumber>
<BatchNumber>234</BatchNumber>
<Quantity>2.000000</Quantity>
<BaseLineNumber>2</BaseLineNumber>
</BatchNumber>
</BatchNumbers>
</ProductionOrderLine>
<ProductionOrderLine>
<LineNumber>3</LineNumber>
<BatchNumbers/>
</ProductionOrderLine>
</ProductionOrder>
What I have tried:
I try to load data by:
Dim dsProd As DataSet = New DataSet() dsProd.ReadXml("TestProd5.xml")
Works quite well, except elements <BatchNumber>234</BatchNumber>
is ommitted in dataset. As I assume reason is parent element with same name. I need this value in
dataset-object. What canI do?
Any help is welcome.
Manfred
There's few ways to load XML data, using:
1) XmlDocument[^]
2) XDocument[^]
3) XmlSerialization[^] => Examples of XML Serialization | Microsoft Docs[^]
[EDIT]
As i mentioned eariler, you can use XDocument class to read your data intoDataSet
object. This is an idea:
Function LoadDataIntoDataSet() As DataSet Dim xNamespace As XNamespace = "http://www.sap.com/SBO/DIS" Dim xDoc As XDocument = XDocument.Parse(GetXmlData()) Dim ds As DataSet = New DataSet() Dim pl As DataTable = New DataTable() pl.Columns.Add(New DataColumn("LineNumber", Type.GetType("System.Int32"))) Dim bn As DataTable = New DataTable() bn.Columns.Add(New DataColumn("LineNumber", Type.GetType("System.Int32"))) bn.Columns.Add(New DataColumn("BatchNumber", Type.GetType("System.Int32"))) bn.Columns.Add(New DataColumn("Quantity", Type.GetType("System.String"))) bn.Columns.Add(New DataColumn("BaseLineNumber", Type.GetType("System.Int32"))) For Each pol As XElement In xDoc.Descendants(xNamespace + "ProductionOrderLine") pl.Rows.Add(New Object(){pol.Element(xNamespace + "LineNumber").Value}) For Each ban As XElement In pol.Descendants(xNamespace + "BatchNumber").Where(Function(x) x.Descendants.Count>0) bn.Rows.Add(New Object() _ { _ pol.Element(xNamespace + "LineNumber").Value, _ ban.Element(xNamespace + "BatchNumber").Value, _ ban.Element(xNamespace + "Quantity").Value, _ ban.Element(xNamespace + "BaseLineNumber").Value _ }) Next Next ds.Tables.Add(pl) ds.Tables.Add(bn) Return ds End Function
But, i'd strongly recommend to use serialization (via DataContractSerializer Class (System.Runtime.Serialization) | Microsoft Docs[^]). In this case, you'll need set of definition of classes:
'needs fererence to System.Runtime.Serialization.dll <DataContract([Namespace] := "http://www.sap.com/SBO/DIS")> Public Class ProductionOrder <DataMember> Public AbsoluteEntry As Integer <DataMember> Public ProductionOrderLines As List(Of ProductionOrderLine) End Class <DataContract> Public Class ProductionOrderLine <DataMember> Public LineNumber As Integer <DataMember> Public BatchNumbers As List(Of BatchNumber) End Class <DataContract> Public Class BatchNumber <DataMember> Public BatchNumber As Integer <DataMember> Public Quantity As String <DataMember> Public BaseLineNumber As Integer End Class
Then you'll be able to convert xml data into objects:
'this method you'll need only first time!!! Dim sFileName As String = "FullFileName.xml" Dim xDoc As XDocument = XDocument.Load(sFileName) Dim xns As XNamespace = "http://www.sap.com/SBO/DIS" Dim po As ProductionOrder = New ProductionOrder() po.AbsoluteEntry = xDoc.Root.Element(xns + "AbsoluteEntry").Value po.ProductionOrderLines = New List(Of ProductionOrderLine) For Each pol As XElement In xDoc.Descendants(xns + "ProductionOrderLine") Dim pl As ProductionOrderLine = New ProductionOrderLine() pl.LineNumber = pol.Element(xns + "LineNumber").Value pl.BatchNumbers = New List(Of BatchNumber) For Each ban As XElement In pol.Descendants(xns + "BatchNumber").Where(Function(x) x.Descendants.Count>0) Dim bn As BatchNumber = New BatchNumber() With bn .BatchNumber = ban.Element(xns + "BatchNumber").Value .Quantity = ban.Element(xns + "Quantity").Value .BaseLineNumber = ban.Element(xns + "BaseLineNumber").Value End With pl.BatchNumbers.Add(bn) Next po.ProductionOrderLines.Add(pl) Next 'now you can write your objects into proper way: WriteObject(sFileName, po) 'read it again: po = ReadObject(sFileName) 'gotcha!
The methods to read/write object:
Sub WriteObject(_fileName As String, po As ProductionOrder) Using writer As FileStream = New FileStream(_fileName, FileMode.Create) Dim knownTypes() AS Type = New Type() {GetType(ProductionOrder), GetType(ProductionOrder), GetType(BatchNumber) } Dim dcs As DataContractSerializer = New DataContractSerializer(GetType(ProductionOrder), knownTypes) dcs.WriteObject(writer, po) writer.Close() End Using End Sub Function ReadObject(_fileName As String) As ProductionOrder Dim po As ProductionOrder = New ProductionOrder() Using fs As FileStream = New FileStream(_fileName, FileMode.Open) Dim reader As XmlDictionaryReader = XmlDictionaryReader.CreateTextReader(fs, New XmlDictionaryReaderQuotas()) Dim knownTypes() AS Type = New Type() {GetType(ProductionOrder), GetType(ProductionOrder), GetType(BatchNumber) } Dim dcs As DataContractSerializer = New DataContractSerializer(GetType(ProductionOrder), knownTypes) po = DirectCast(dcs.ReadObject(reader, True), ProductionOrder) reader.Close() fs.Close() End Using Return po End Function
This is the way you can deal with xml data and custom objects!
这篇关于将XML内容加载到数据集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!