我在VB.net中编写了一个程序,它允许我使用OleDB字符串将Excel文件转换为XML,将其读入Datatable,然后读入数据集,最后将数据集转换为XML,可以保存到另一个文件中。
现在我很难理解如何让XML以特定的方式保存元素,基本上看起来像采购订单?
我的excel文件的所有当前代码和屏幕截图如下所示。任何帮助表示赞赏。
如果我的代码工作,XML文件应该如何查看:
<?xml version="1.0" encoding="ASCII" standalone="yes"?>
<CustomerPurchaseOrder xmlns="http://www.dummysite.com/">
<CustomerPurchaseOrderFile>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
<OrderDate>2015-12-11</OrderDate>
<SpecialInstructions>Leave at front door</SpecialInstructions>
<LineItems>
<LineItem>
<ItemDescription>Brown Shirt</ItemDescription>
<QTY>1</QTY>
<Price>$12.99</Price>
</LineItem>
<LineItem>
<ItemDescription>Black Shoes Pair</ItemDescription>
<QTY>1</QTY>
<Price>$45.89</Price>
</LineItem>
<LineItem>
<ItemDescription>Oranges</ItemDescription>
<QTY>5</QTY>
<Price>$8.99</Price>
</LineItem>
</LineItems>
<FirstName>Lisa</FirstName>
<LastName>Lane</LastName>
<OrderDate>2016-01-12</OrderDate>
<SpecialInstructions />
<LineItems>
<LineItem>
<ItemDescription>Wheat Bread Loaf</ItemDescription>
<QTY>3</QTY>
<Price>$5.99</Price>
</LineItem>
<LineItem>
<ItemDescription>TV Samsung 40"</ItemDescription>
<QTY>1</QTY>
<Price> $539.99</Price>
</LineItem>
</LineItems>
</CustomerPurchaseOrderFile>
</CustomerPurchaseOrder>
我目前得到的 - 不是我想要的:
<?xml version="1.0" standalone="yes"?>
<CustomerPurchaseOrder xmlns="http://www.dummysite.com">
<CustomerPurchaseOrderFile>
<FirstName>John</FirstName>
<LastName>Smith</LastName>
<OrderDate>2015-12-11T00:00:00-08:00</OrderDate>
<SpecialInstructions>Leave at front door</SpecialInstructions>
<ItemDescription>Brown Shirt</ItemDescription>
<QTY>1</QTY>
<Price>12.99</Price>
</CustomerPurchaseOrderFile>
<CustomerPurchaseOrderFile>
<ItemDescription>Black Shoes Pair</ItemDescription>
<QTY>1</QTY>
<Price>45.89</Price>
</CustomerPurchaseOrderFile>
<CustomerPurchaseOrderFile>
<ItemDescription>Oranges</ItemDescription>
<QTY>5</QTY>
<Price>8.99</Price>
</CustomerPurchaseOrderFile>
<CustomerPurchaseOrderFile>
<FirstName>Lisa</FirstName>
<LastName>Lane</LastName>
<OrderDate>2016-01-12T00:00:00-08:00</OrderDate>
<ItemDescription>Wheat Bread Loaf</ItemDescription>
<QTY>3</QTY>
<Price>5.99</Price>
</CustomerPurchaseOrderFile>
<CustomerPurchaseOrderFile>
<ItemDescription>TV Samsung 40"</ItemDescription>
<QTY>1</QTY>
<Price>539.99</Price>
</CustomerPurchaseOrderFile>
</CustomerPurchaseOrder>
我的VB.Net代码
Imports System.Data.OleDb
Public Class Form1
Dim myDS As DataSet
Dim myDT As DataTable = New DataTable("CustomerPurchaseOrderFile")
Dim myFilePath As String()
'Load Excel File Button
Private Sub loadFileBtn_Click(sender As Object, e As EventArgs) Handles loadFileBtn.Click
'choose excel file
'file dialog box properties
OpenFileDialog1.Filter = "Excel Files (*.xls, *.xlsx)|*.xls;*.xlsx"
OpenFileDialog1.FilterIndex = 2
OpenFileDialog1.InitialDirectory = "C:\"
saveXMLBtn.Enabled = False
Dim checkOpenDialog As DialogResult = OpenFileDialog1.ShowDialog()
Dim myConnection As String, excelConn As OleDbConnection
Dim myAdapter As OleDbDataAdapter
'import file using OleDB connections into datatable -> dataset -> xml
Try
'disable save button if no file is loaded
If checkOpenDialog = DialogResult.Cancel Then
saveXMLBtn.Enabled = False
ElseIf checkOpenDialog = DialogResult.None Then
saveXMLBtn.Enabled = False
ElseIf checkOpenDialog = DialogResult.OK Then
myFilePath = OpenFileDialog1.FileNames
myConnection = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + myFilePath(0) + ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1;"""
excelConn = New OleDbConnection(myConnection)
excelConn.Open()
myAdapter = New OleDbDataAdapter("select * from [Sheet1$]", excelConn)
myDT = New DataTable()
myDS = New DataSet()
myDS.Tables.Add(myDT)
myDS.Merge(myDT)
myDS.DataSetName = "CustomerPurchaseOrder"
myDS.Namespace = "http://www.dummysite.com"
myDS.Prefix = ""
myAdapter.Fill(myDS, "CustomerPurchaseOrderFile")
myDS.AcceptChanges()
excelConn.Close()
'dataset -> string storage
Dim storeXML As String = myDS.GetXml
'preview in text box
xmlPreviewBox.Text = storeXML
End If
'save dataset to string
Catch ex As Exception
MsgBox(ex.ToString)
Finally
If myFilePath IsNot Nothing Then
MsgBox("Preview of XML File Loaded.")
saveXMLBtn.Enabled = True
End If
End Try
End Sub
'Save Converted Excel to XML File
Private Sub saveXMLBtn_Click(sender As Object, e As EventArgs) Handles saveXMLBtn.Click
'file dialog box properties
SaveFileDialog1.Filter = "XML Files (*.xml)|*.xml"
SaveFileDialog1.FilterIndex = 1
SaveFileDialog1.InitialDirectory = "C:\"
saveXMLBtn.Enabled = False
SaveFileDialog1.ShowDialog()
myFilePath = SaveFileDialog1.FileNames
Try
If SaveFileDialog1.FileName <> "" Then
'myDS.WriteXml(myFilePath, XmlWriteMode.IgnoreSchema)
myDS.WriteXml(myFilePath(0)) 'works and above works the same
End If
Catch ex As Exception
MsgBox(ex.ToString)
Finally
MsgBox("XML File Saved Successfully.")
End Try
End Sub
End Class
答案 0 :(得分:0)
看起来有三个不同的部分。第一个是PO组,所以像这样定义
Dim protoPurchaseOrders As XElement = <PurchaseOrders>
</PurchaseOrders>
下一部分是PO
Dim protoPO As XElement = <PO>
<firstname></firstname>
<lastame></lastame>
<orderdate></orderdate>
<specialinstructions></specialinstructions>
<items></items>
</PO>
最后您将获得将添加到PO中的项目的订单项。
Dim protoitem As XElement = <item>
<description></description>
<QTY></QTY>
<price></price>
</item>
这些原型可用于创建您想要的东西。下面是一些代码模拟一组包含一些订单项的两个订单项的代码。 请注意,原型仅用于创建新的xelements 。
Dim orderfile As New XElement(protoPurchaseOrders)
For x As Integer = 1 To 2 'simulate two customer PO's
Dim aPO As New XElement(protoPO) 'create a PO and fill in the blanks
aPO.<firstname>.Value = x.ToString
aPO.<lastame>.Value = x.ToString
aPO.<orderdate>.Value = DateTime.Now.AddDays(x).ToShortDateString
aPO.<specialinstructions>.Value = "SI " & x.ToString
For i As Integer = x To 3 'create line items and fill in the blanks
Dim item As New XElement(protoitem)
item.<description>.Value = "desc " & i.ToString
item.<QTY>.Value = i.ToString
item.<price>.Value = i.ToString("c2")
aPO.<items>.LastOrDefault.Add(item) 'add item to PO
Next
orderfile.Add(aPO) 'add PO to orders
Next
'orderfile.Save("path goes here")
这增加了一个抽象级别(PO),而不是“你想要的”,但我认为这是必要的。
以上的输出是
<PurchaseOrders>
<PO>
<firstname>1</firstname>
<lastame>1</lastame>
<orderdate>1/30/2016</orderdate>
<specialinstructions>SI 1</specialinstructions>
<items>
<item>
<description>desc 1</description>
<QTY>1</QTY>
<price>$1.00</price>
</item>
<item>
<description>desc 2</description>
<QTY>2</QTY>
<price>$2.00</price>
</item>
<item>
<description>desc 3</description>
<QTY>3</QTY>
<price>$3.00</price>
</item>
</items>
</PO>
<PO>
<firstname>2</firstname>
<lastame>2</lastame>
<orderdate>1/31/2016</orderdate>
<specialinstructions>SI 2</specialinstructions>
<items>
<item>
<description>desc 2</description>
<QTY>2</QTY>
<price>$2.00</price>
</item>
<item>
<description>desc 3</description>
<QTY>3</QTY>
<price>$3.00</price>
</item>
</items>
</PO>
</PurchaseOrders>
答案 1 :(得分:0)
通过创建子DataTable并使用嵌套的DataRelation链接它们,您几乎可以使用数据集执行此操作(有关嵌套DataRelations的详细信息,请参阅https://msdn.microsoft.com/en-us/library/7sfkwf9s%28v=vs.110%29.aspx)。但是,您必须处理“扁平”Excel数据以适应新结构,并且您需要使用主键将子表链接到父表(这可能会影响XML输出)。
可能最好使用数据集加载Excel工作表进行处理,然后以编程方式生成XML(参见https://msdn.microsoft.com/en-us/library/bb387068%28v=vs.110%29.aspx)。
答案 2 :(得分:0)
我必须弄清楚如何使用Xdocument和Xelement使dbasnett的解决方案工作并进行一些其他调整以使xml以我需要的正确格式运行,所以这是我的最终解决方案。谢谢大家的回复。
Dim xQuery As IEnumerable(Of XElement) = From i In xEleDoc.Elements() Select i
For Each i As XElement In xQuery.Elements("FirstName") 'simulate customer PO
Dim aPO As New XElement(customerInfo) 'create a PO and fill in the values
aPO.<FirstName>.Value = xQuery.Elements("FirstName").Value
aPO.<LastName>.Value = xQuery.Elements("LastName").Value
aPO.<OrderDate>.Value = Date.Parse(xQuery.Elements("OrderDate").Value).ToString("yyyy-MM-dd")
aPO.<SpecialInstructions>.Value = xQuery.Elements("SpecialInstructions").Value
For Each line In xQuery 'create line items and fill in the values
Dim item As New XElement(itemsOrdered)
item.<ItemDescription>.Value = line.Elements("ItemDescription").Value
item.<QTY>.Value = line.Elements("QTY").Value
item.<Price>.Value = line.Elements().Last.Value
aPO.<LineItems>.LastOrDefault.Add(item) 'add item to PO
Next
orderfile.Add(aPO) 'add created POs to orderfile
Next