2016-01-29 91 views
0

我在VB.net中編寫了一個程序,該程序允許我使用OleDB字符串將Excel文件轉換爲XML,將其讀入數據表,然後轉換爲數據集,並最終轉換數據集爲XML,可以將其保存到另一個文件中。VB.net數據集到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 

My Excel File Screenshot

+1

XML到數據集和背面是醜陋的,特別是如果你有相關的表。我認爲簡單地從Excel中提取數據,然後插入到表中並生成XML文件會更容易。根據我的經驗,瀏覽一下您生成的XML文件,就會得到多個表格,就像我說的那樣,這會導致XML混亂。 – Tim

+0

所以,你說要忽略數據集?所以基本上excel - > datatable - > xml ..我可以做到這一點,但我仍然會被困在如何將XML轉換爲我需要的正確的採購訂單的格式。我對此沒有太多經驗,所以我願意接受建議和較不笨的代碼。 – Daphne

+0

除非將數據保存到數據庫中,否則應該可以完全忽略「DataSet/DataTable」 - 只需讀取Excel文件並將其轉換爲您需要的XML即可。你能發佈一個Excel格式的樣本嗎? – Tim

回答

0

它看起來像有三個不同的部分。第一個是團寶的,所以它定義成這樣

Dim protoPurchaseOrders As XElement = <PurchaseOrders> 
              </PurchaseOrders> 

接下來的部分是一個PO

Dim protoPO As XElement = <PO> 
            <firstname></firstname> 
            <lastame></lastame> 
            <orderdate></orderdate> 
            <specialinstructions></specialinstructions> 
            <items></items> 
           </PO> 

最後你將被添加到項目中寶線項目。

Dim protoitem As XElement = <item> 
            <description></description> 
            <QTY></QTY> 
            <price></price> 
           </item> 

這些原型可以用來創建你想要的。以下是一些代碼,用於模擬一組包含一些訂單項的採購訂單。 請注意,原型僅用於創建新的元素

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> 
+0

我從來沒有使用Xelement ..這是從openfiledialog工作嗎?我發現這個鏈接:[MSDN:如何從文件加載XML](https://msdn.microsoft.com/en-us/library/bb384609.aspx) 該鏈接是相關的如何做到這一點? – Daphne

+0

這有助於至少讓我在正確的方向。我會發布我的最終解決方案。 – Daphne

0

你幾乎可以通過創建一個孩子DataTable,並使用嵌套的DataRelation鏈接他們這樣做有一個數據集(見https://msdn.microsoft.com/en-us/library/7sfkwf9s%28v=vs.110%29.aspx嵌套DataRelations的細節)。但是,您必須處理'平面'Excel數據以適應新結構,並且您需要一個主鍵將子錶鏈接到父級(這可能會影響XML輸出)。

可能最好使用數據集來加載Excel工作表並進行編程(參見https://msdn.microsoft.com/en-us/library/bb387068%28v=vs.110%29.aspx)。

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 
相關問題