将XML内容加载到数据集 [英] Load XML-content to dataset

查看:86
本文介绍了将XML内容加载到数据集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



需要一点帮助才能从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 into DataSet 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆