最好的.net方法來創建XML文檔

[英]Best .net Method to create an XML Doc


I am trying to figure out what the best method is for writing an XML Document. Below is a simple example of what I am trying to create off of data I am pulling from our ERP system. I have read about XMLWriter, but thought I would see if there are any other better methods. Any suggestions would be greatly appreciated.

我試圖找出編寫XML文檔的最佳方法。下面是一個簡單的例子,說明我試圖從我的ERP系統中提取的數據。我已經閱讀了有關XMLWriter的內容,但我想我會看看是否還有其他更好的方法。任何建議將不勝感激。

Example XML:

示例XML:

<?xml version="1.0"?>
<Orders>
  <Order OrderNumber="12345">
    <ItemNumber>0123993587</ItemNumber>
    <QTY>10</QTY>
    <WareHouse>PA019</WareHouse>
  </Order>
  <Order OrderNumber="12346">
    <ItemNumber>0123993587</ItemNumber>
    <QTY>9</QTY>
    <WareHouse>PA019</WareHouse>
  </Order>
  <Order OrderNumber="12347">
    <ItemNumber>0123993587</ItemNumber>
    <QTY>8</QTY>
    <WareHouse>PA019</WareHouse>
  </Order>
</Orders>

11 个解决方案

#1


23  

Josh's answer shows how easy it is to create a single element in LINQ to XML... it doesn't show how it's also hugely easy to create multiple elements. Suppose you have a List<Order> called orders... you can create the whole document like this:

Josh的回答顯示了在LINQ to XML中創建單個元素是多么容易......它沒有顯示創建多個元素也非常容易。假設您有一個名為Order的Order ...您可以像這樣創建整個文檔:

var xml = new XElement("Orders",
    orders.Select(order =>
        new XElement("Order",
            new XAttribute("OrderNumber", order.OrderNumber),
            new XElement("ItemNumber", order.ItemNumber),
            new XElement("QTY", order.Quantity),
            new XElement("Warehouse", order.Warehouse)
        ));
);

LINQ to XML makes constructing XML incredibly easy. It also has support for XML namespaces which is pretty easy too. For instance, if you wanted your elements to be in a particular namespace, you'd just need:

LINQ to XML使得構建XML非常容易。它還支持XML命名空間,這也非常簡單。例如,如果您希望元素位於特定的命名空間中,您只需要:

XNamespace ns = "http://your/namespace/here";
var xml = new XElement(ns + "Orders",
    orders.Select(order =>
        new XElement(ns + "Order",
... (rest of code as before)

LINQ to XML is the best XML API I've worked with... it's great for querying too.

LINQ to XML是我使用過的最好的XML API ...它也非常適合查詢。

#2


9  

I would suggest using the classes in System.Xml.Linq.dll which contain an XML DOM API that allows for easy build-up of XML structures due to the way the contructors are designed. Trying to create an XML structure using the System.Xml classes is very painful because you have to create them detached then separately add them into the document.

我建議使用System.Xml.Linq.dll中的類,它們包含一個XML DOM API,由於構造器的設計方式,它允許輕松構建XML結構。嘗試使用System.Xml類創建XML結構非常痛苦,因為您必須創建它們分離然后單獨將它們添加到文檔中。

Here's an example of XLinq vs. System.Xml to create a DOM from scratch. Your eyes will bleed when you see the System.Xml example.

以下是XLinq與System.Xml的示例,用於從頭開始創建DOM。當您看到System.Xml示例時,您的眼睛會流血。

Here's a quick example of how you would use XLinq to build up part of your doc.

這是一個快速示例,說明如何使用XLinq構建部分文檔。

var xml = new XElement("Orders",
    new XElement("Order",
        new XAttribute("OrderNumber", 12345),
        new XElement("ItemNumber", "01234567"),
        new XElement("QTY", 10),
        new XElement("Warehouse", "PA019")
    )
);

TIP Although it's a little unorthodox (though no worse than some of the language butchering that has become popular lately), I have on occasion used C#'s type aliasing feature to minimize the code even further:

提示雖然它有點不正統(雖然不比最近流行的一些語言屠宰更糟糕),但我偶爾使用C#的類型別名功能來進一步減少代碼:

using XE = System.Xml.Linq.XElement;
using XA = System.Xml.Linq.XAttribute;
...
var xml = new XE("Orders",
    new XE("Order",
        new XA("OrderNumber", 12345),
        new XA("ItemNumber", "01234567"),
        new XA("QTY", 10),
        new XA("Warehouse", "PA019")
    )
);

#3


4  

What about this : create a class "Order" and one "Orders", and then serialize those out to XML - seems a lot easier to me than creating the XML bit by bit from hand....

那怎么樣:創建一個類“Order”和一個“Orders”,然后將它們序列化為XML - 對我來說比從手工創建XML更容易....

Since you say you're pulling the data off your ERP, you probably already have objects and classes for "Order" and so on - maybe it's sufficient to put a few [XmlElement] attributes on your classes and you're good to go!

既然你說你正在從你的ERP中提取數據,那么你可能已經有了“Order”的對象和類等等 - 也許只需要在你的類上放幾個[XmlElement]屬性就可以了!

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace XmlLinqTest
{
    [Serializable]
    [XmlRoot(Namespace = "")]
    public class Orders
    {
        private List<Order> _orders = new List<Order>();

        /// <remarks/>
        [XmlElement("Order")]
        public List<Order> OrderList
        {
            get { return _orders; }
        }
    }

    /// <remarks/>
    [Serializable]
    public class Order
    {
        /// <remarks/>
        [XmlElement]
        public string ItemNumber { get; set; }

        [XmlElement]
        public int QTY { get; set; }

        /// <remarks/>
        [XmlElement]
        public string WareHouse { get; set; }

        /// <remarks/>
        [XmlAttribute]
        public string OrderNumber { get; set; }
    }
}

and in your main app something like this:

並在您的主應用程序中這樣的事情:

Orders orders = new Orders();

Order work = new Order() { ItemNumber = "0123993587", OrderNumber = "12345", QTY = 10, WareHouse = "PA019" };
orders.OrderList.Add(work);

work = new Order() { ItemNumber = "0123993587", OrderNumber = "12346", QTY = 9, WareHouse = "PA019" };
orders.OrderList.Add(work);

work = new Order() { ItemNumber = "0123993587", OrderNumber = "12347", QTY = 8, WareHouse = "PA019" };
orders.OrderList.Add(work);

XmlSerializer ser = new XmlSerializer(typeof(Orders));

using(StreamWriter wr = new StreamWriter(@"D:\testoutput.xml", false, Encoding.UTF8))
{
    ser.Serialize(wr, orders);
}

Working with objects and then serializing them out to disk seems a lot easier to me than fiddling around with XDocument and other APIs.

使用對象然后將它們序列化到磁盤似乎比擺弄XDocument和其他API要容易得多。

#4


2  

If your use case is simple, nothing could possibly simpler and easier to use than XmlTextWriter. That said, one alternative would be to use an XmlDocument object to create and append all of your nodes. But I think it's easier to write and maintain code that uses XmlTextWriter if you're creating a document from scratch rather than manipulating one. Using XmlTextWriter should be very straightforward:

如果您的用例很簡單,那么沒有什么比XmlTextWriter更簡單,更容易使用了。也就是說,一種替代方法是使用XmlDocument對象來創建和附加所有節點。但是,如果您從頭開始創建文檔而不是操作文檔,我認為編寫和維護使用XmlTextWriter的代碼會更容易。使用XmlTextWriter應該非常簡單:

        StringBuilder output = new StringBuilder();
        XmlWriter writer = XmlWriter.Create(output);
        writer.WriteProcessingInstruction("xml", "version=\"1.0\"");
        writer.WriteStartElement("Orders");
        //...start loop...
        writer.WriteStartElement("Order");
        writer.WriteAttributeString("OrderNumber", "12345");
        writer.WriteElementString("ItemNumber", "0123993587");
        writer.WriteElementString("QTY", "10");
        writer.WriteElementString("WareHouse", "PA019");
        writer.WriteEndElement();
        //...loop...
        writer.WriteEndElement();
        writer.Close();

#5


0  

I had to create following XML document having some part of it parametrized.

我必須創建以下XML文檔,其中一部分參數化。

<?xml version="1.0" encoding="utf-8"?>
<wap-provisioningdoc>
  <characteristic type="BOOTSTRAP">
    <parm name="NAME" value="SYNCSETTINGS" />
  </characteristic>
  <characteristic type="APPLICATION">
    <parm name="APPID" value="w5" />
    <parm name="TO-NAPID" value="INTERNET" />
    <parm name="NAME" value="SYNCSETTINGS" />
    <parm name="ADDR" value="http://syncserver/sync" />
    <characteristic type="RESOURCE">
      <parm name="URI" value="pb" />
      <parm name="NAME" value="Contacts DB" />
      <parm name="AACCEPT" value="text/x-vcard" />
    </characteristic>
    <characteristic type="RESOURCE">
      <parm name="URI" value="cal" />
      <parm name="NAME" value="Calendar DB" />
      <parm name="AACCEPT" value="text/x-vcalendar" />
    </characteristic>
    <characteristic type="RESOURCE">
      <parm name="URI" value="notes" />
      <parm name="NAME" value="Notes DB" />
      <parm name="AACCEPT" value="text/plain" />
    </characteristic>
    <characteristic type="APPAUTH">
      <parm name="AAUTHNAME" value="username" />
      <parm name="AAUTHSECRET" value="password" />
    </characteristic>
  </characteristic>
</wap-provisioningdoc>

And here's my code that does this with single LINQ statement.

這是我用單個LINQ語句執行此操作的代碼。

Make a note that creating XML document above using LINQ and saving it to XML file preserves the XML document formatting and keeps line-breaks and carriage-returns that makes the document properly tabified.

請注意,使用LINQ創建上面的XML文檔並將其保存到XML文件會保留XML文檔格式並保留換行符和回車符,從而使文檔正確制表。

public string CreateOTAXmlFile(string Username, string Password)
    {
        var ota = new XDocument(
                    new XElement("wap-provisioningdoc",
                        new XElement("characteristic", new XAttribute("type", "BOOTSTRAP"),
                            new XElement("parm", new XAttribute("name", "NAME"), new XAttribute("value", "SYNCSETTINGS"))
                                    ),
                        new XElement("characteristic", new XAttribute("type", "APPLICATION"),
                            new XElement("parm", new XAttribute("name", "APPID"), new XAttribute("value", "w5")),
                            new XElement("parm", new XAttribute("name", "TO-NAPID"), new XAttribute("value", "INTERNET")),
                            new XElement("parm", new XAttribute("name", "NAME"), new XAttribute("value", "SYNCSETTINGS")),
                            new XElement("parm", new XAttribute("name", "ADDR"), new XAttribute("value", "http://syncserver/sync")),
                            new XElement("characteristic", new XAttribute("type", "RESOURCE"),
                                new XElement("parm", new XAttribute("name", "URI"), new XAttribute("value", "pb")),
                                new XElement("parm", new XAttribute("name", "NAME"), new XAttribute("value", "Contacts DB")),
                                new XElement("parm", new XAttribute("name", "AACCEPT"), new XAttribute("value", "text/x-vcard"))
                                        ),
                            new XElement("characteristic", new XAttribute("type", "RESOURCE"),
                                new XElement("parm", new XAttribute("name", "URI"), new XAttribute("value", "cal")),
                                new XElement("parm", new XAttribute("name", "NAME"), new XAttribute("value", "Calendar DB")),
                                new XElement("parm", new XAttribute("name", "AACCEPT"), new XAttribute("value", "text/x-vcalendar"))
                                        ),
                            new XElement("characteristic", new XAttribute("type", "RESOURCE"),
                                new XElement("parm", new XAttribute("name", "URI"), new XAttribute("value", "notes")),
                                new XElement("parm", new XAttribute("name", "NAME"), new XAttribute("value", "Notes DB")),
                                new XElement("parm", new XAttribute("name", "AACCEPT"), new XAttribute("value", "text/plain"))
                                        ),
                            new XElement("characteristic", new XAttribute("type", "APPAUTH"),
                                new XElement("parm", new XAttribute("name", "AAUTHNAME"), new XAttribute("value", Username)),
                                new XElement("parm", new XAttribute("name", "AAUTHSECRET"), new XAttribute("value", Password))
                                        )
                                    )
                                )
                            );

        ota.Save(Server.MapPath("~/OTA/") + Username + ".xml");
        return (ota.ToString());

    }

#6


0  

// Create the xml document containe
XmlDocument doc = new XmlDocument();// Create the XML Declaration, and append it to XML document
XmlDeclaration dec = doc.CreateXmlDeclaration("1.0", null, null);
doc.AppendChild(dec);// Create the root element
XmlElement root = doc.CreateElement("Library");
doc.AppendChild(root);
// Create Books
// Note that to set the text inside the element,
// you use .InnerText instead of .Value (which will throw an exception).
// You use SetAttribute to set attribute
XmlElement book = doc.CreateElement("Book");
book.SetAttribute("BookType", "Hardcover");
XmlElement title = doc.CreateElement("Title");
title.InnerText = "Door Number Three";
XmlElement author = doc.CreateElement("Author");
author.InnerText = "O'Leary, Patrick";
book.AppendChild(title);
book.AppendChild(author);
root.AppendChild(book);
book = doc.CreateElement("Book");
book.SetAttribute("BookType", "Paperback");
title = doc.CreateElement("Title");
title.InnerText = "Lord of Light";
author = doc.CreateElement("Author");
author.InnerText = "Zelanzy, Roger";
book.AppendChild(title);
book.AppendChild(author);
root.AppendChild(book);
string xmlOutput = doc.OuterXml;
The same code but using an XMLWriter to a memory stream.

XmlWriterSettings wSettings = new XmlWriterSettings();
wSettings.Indent = true;
MemoryStream ms = new MemoryStream();
XmlWriter xw = XmlWriter.Create(ms, wSettings);// Write Declaration
xw.WriteStartDocument();
// Write the root node
xw.WriteStartElement("Library");
// Write the books and the book elements
xw.WriteStartElement("Book");
xw.WriteStartAttribute("BookType");
xw.WriteString("Hardback");
xw.WriteEndAttribute();
xw.WriteStartElement("Title");
xw.WriteString("Door Number Three");
xw.WriteEndElement();
xw.WriteStartElement("Author");
xw.WriteString("O'Leary, Patrick");
xw.WriteEndElement();
xw.WriteEndElement();
// Write another book
xw.WriteStartElement("Book");
xw.WriteStartAttribute("BookType");
xw.WriteString("Paperback");
xw.WriteEndAttribute();
xw.WriteStartElement("Title");
xw.WriteString("Lord of Light");
xw.WriteEndElement();
xw.WriteStartElement("Author");
xw.WriteString("Zelanzy, Roger");
xw.WriteEndElement();
xw.WriteEndElement();
// Close the document
xw.WriteEndDocument();
// Flush the write
xw.Flush();
Byte[] buffer = new Byte[ms.Length];
buffer = ms.ToArray();
string xmlOutput = System.Text.Encoding.UTF8.GetString(buffer);

#7


0  

If you don't want (or can't) to use LINQ to XML, neither to duplicate your Order class to include XML serialization, and thinks XmlWriter is too much verbose, you can go with plain classical XmlDocument class:

如果您不希望(或不能)使用LINQ to XML,既不復制Order類以包含XML序列化,又認為XmlWriter太冗長,您可以使用簡單的經典XmlDocument類:

// consider Order class that data structure you receive from your ERP system
List<Order> orders = YourERP.GetOrders();
XmlDocument xml = new XmlDocument();
xml.AppendChild(xml.CreateElement("Orders"));
foreach (Order order in orders)
{
    XmlElement item = xml.CreateElement("Order");
    item.SetAttribute("OrderNumber", order.OrderNumber);
    item.AppendChild(xml.CreateElement("ItemNumber")).Value = order.ItemNumber;
    item.AppendChild(xml.CreateElement("QTY"       )).Value = order.Quantity;
    item.AppendChild(xml.CreateElement("WareHouse" )).Value = order.WareHouse;
    xml.DocumentElement.AppendChild(item);
}

#8


0  

There are a lot of good suggestions in this thread, but one that hasn't been mentioned: Defining an ADO DataSet and serializing/deserializing using the ReadXml and WriteXml methods. This can be a very simple and attractive solution. Your XML isn't in quite the right format, but it's close.

這個帖子中有很多好的建議,但是沒有提到過:使用ReadXml和WriteXml方法定義ADO DataSet和序列化/反序列化。這可能是一個非常簡單和有吸引力的解決方案您的XML格式不正確,但它很接近。

#9


0  

I found it largely depends how complex your original data is.

我發現它在很大程度上取決於原始數據的復雜程度。

If your data is nicely organized in objects and it is sufficient to dump it in XML, Linq is very verbose and powerful. But as soon as there are object inter-dependencies, I don't think you want to go with the Linq one-liner, as this is real pain to debug and/or extend.

如果您的數據在對象中組織得很好並且將其轉儲為XML就足夠了,Linq非常冗長且功能強大。但是只要有對象相互依賴,我就不認為你想要使用Linq單行,因為這是調試和/或擴展的真正痛苦。

For those cases, I'd prefer to go with XmlDocument, create a help method to facilitate adding attributes to an element (see below), and use Linq in foreach loops around the XML creation blocks.

對於這些情況,我更喜歡使用XmlDocument,創建一個幫助方法以便於向元素添加屬性(見下文),並在圍繞XML創建塊的foreach循環中使用Linq。

private void XAttr(ref XmlNode xn, string nodeName, string nodeValue)
{
    XmlAttribute result = xn.OwnerDocument.CreateAttribute(nodeName); 
    result.InnerText = nodeValue;
    xn.Attributes.Append(result);
}

#10


0  

There's a new language called XCST that compiles to C#.

有一種叫做XCST的新語言編譯成C#。

<c:template name='c:initial-template' expand-text='yes'>
   <c:param name='orders' as='IEnumerable&lt;Order>'/>

   <Orders>
      <c:for-each name='order' in='orders'>
         <Order OrderNumber='{order.Number}'>
            <ItemNumber>{order.ItemNumber}</ItemNumber>
            <QTY>{order.Quantity}</QTY>
            <WareHouse>{order.WareHouse}</WareHouse>
         </Order>
      </c:for-each>
   </Orders>
</c:template>

#11


-2  

You just right click on your code window , select InsertSnippet follow this Link

您只需右鍵單擊代碼窗口,選擇InsertSnippet,然后單擊此鏈接

 Data-Xml.....>Xml>Xmlcreate

its very easy

它非常容易


注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2010/01/16/725ece0e22920098f36e24bdc8e2ad21.html



 
粤ICP备14056181号  © 2014-2021 ITdaan.com