Как работать с XML в C#



каков наилучший способ работы с XML-документами, XSD и т. д. В C# 2.0?



классы и т. д. Каковы лучшие практики синтаксического анализа и создания XML-документов и т. д.



EDIT: .Net 3.5 предложения также приветствуются.

1439   12  

12 ответов:

основные средства чтения и записи в C# 2.0 осуществляется через XmlDocument класса. Вы можете загрузить большинство своих настроек непосредственно в XmlDocument через XmlReader, который он принимает.

загрузка XML напрямую

XmlDocument document = new XmlDocument();
document.LoadXml("<People><Person Name='Nick' /><Person Name='Joe' /></People>");

загрузка XML из файла

XmlDocument document = new XmlDocument();
document.Load(@"C:\Path\To\xmldoc.xml");
// Or using an XmlReader/XmlTextReader
XmlReader reader = XmlReader.Create(@"C:\Path\To\xmldoc.xml");
document.Load(reader);

Я нахожу самый простой / быстрый способ чтения XML-документа с помощью XPath.

чтение XML-документа с помощью XPath (с помощью XmlDocument, который позволяет нас редактировать)

XmlDocument document = new XmlDocument();
document.LoadXml("<People><Person Name='Nick' /><Person Name='Joe' /></People>");

// Select a single node
XmlNode node = document.SelectSingleNode("/People/Person[@Name = 'Nick']");

// Select a list of nodes
XmlNodeList nodes = document.SelectNodes("/People/Person");

если вам нужно работать с документами XSD для проверки XML-документа, вы можете использовать это.

проверка XML-документов на xsd-схемы

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidateType = ValidationType.Schema;
settings.Schemas.Add("", pathToXsd); // targetNamespace, pathToXsd

XmlReader reader = XmlReader.Create(pathToXml, settings);
XmlDocument document = new XmlDocument();

try {
    document.Load(reader);
} catch (XmlSchemaValidationException ex) { Trace.WriteLine(ex.Message); }

проверка XML против XSD на каждом узле (обновление 1)

XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidateType = ValidationType.Schema;
settings.Schemas.Add("", pathToXsd); // targetNamespace, pathToXsd
settings.ValidationEventHandler += new ValidationEventHandler(settings_ValidationEventHandler);

XmlReader reader = XmlReader.Create(pathToXml, settings);
while (reader.Read()) { }

private void settings_ValidationEventHandler(object sender, ValidationEventArgs args)
{
    // e.Message, e.Severity (warning, error), e.Error
    // or you can access the reader if you have access to it
    // reader.LineNumber, reader.LinePosition.. etc
}

написание XML-документа (вручную)

XmlWriter writer = XmlWriter.Create(pathToOutput);
writer.WriteStartDocument();
writer.WriteStartElement("People");

writer.WriteStartElement("Person");
writer.WriteAttributeString("Name", "Nick");
writer.WriteEndElement();

writer.WriteStartElement("Person");
writer.WriteStartAttribute("Name");
writer.WriteValue("Nick");
writer.WriteEndAttribute();
writer.WriteEndElement();

writer.WriteEndElement();
writer.WriteEndDocument();

writer.Flush();

(обновление 1)

в .Net 3.5 с, вы использовать XDocument используется для выполнения подобных задач. Разница однако у вас есть преимущество выполнения запросов LINQ для выбора нужных данных. С добавлением инициализаторов объектов вы можете создать запрос, который даже возвращает объекты вашего собственного определения прямо в самом запросе.

    XDocument doc = XDocument.Load(pathToXml);
    List<Person> people = (from xnode in doc.Element("People").Elements("Person")
                       select new Person
                       {
                           Name = xnode.Attribute("Name").Value
                       }).ToList();

(обновление 2)

хороший способ в .NET 3.5 заключается в использовании XDocument для создания XML ниже. Это делает код похожим на желаемый шаблон выход.

XDocument doc =
        new XDocument(
              new XDeclaration("1.0", Encoding.UTF8.HeaderName, String.Empty),
              new XComment("Xml Document"),
              new XElement("catalog",
                    new XElement("book", new XAttribute("id", "bk001"),
                          new XElement("title", "Book Title")
                    )
              )
        );

создает

<!--Xml Document-->
<catalog>
  <book id="bk001">
    <title>Book Title</title>
  </book>
</catalog>

все остальное не удается, вы можете проверить эту статью MSDN, которая имеет много примеров, которые я обсуждал здесь и многое другое. http://msdn.microsoft.com/en-us/library/aa468556.aspx

Это зависит от размера; для малого и среднего размера xml, DOM, такие как XmlDocument (любые версии C#/.NET) или XDocument (.NET 3.5/C# 3.0) является очевидным победителем. Для использования xsd вы можете загрузить xml с помощью XmlReader, и XmlReader принимает (к создать) an XmlReaderSettings. Объекты XmlReaderSettings имеет - схемы свойство, которое можно использовать для выполнения xsd (или dtd) утверждение.

для записи xml применяются те же самые вещи, отмечая, что немного легче выложить содержимое с помощью LINQ-to-XML (XDocument), чем более старый XmlDocument.

однако для огромного xml DOM может сжать слишком много памяти, и в этом случае вам может потребоваться использовать XmlReader/XmlWriter напрямую.

наконец, для управления xml вы можете использовать XslCompiledTransform (слой xslt).

альтернатива работе с xml работать с объектной моделью; вы можете использовать xsd.exe чтобы создать классы, представляющие xsd-совместимую модель, и просто загрузить xml объекты, манипулируйте им с помощью OO, а затем снова сериализуйте эти объекты; вы делаете это с XmlSerializer.

ответ nyxtom очень хорош. Я бы добавил к этому пару вещей:

Если вам нужен доступ только для чтения к XML-документу,XPathDocument Это гораздо более легкий объект, чем XmlDocument.

обратная сторона использования XPathDocument - вы не можете использовать знакомый SelectNodes и SelectSingleNode способы XmlNode. Вместо этого, вы должны использовать инструменты, что IXPathNavigable обеспечивает: использовать CreateNavigator создать XPathNavigator, и использовать XPathNavigator создать XPathNodeIterators для итерации по спискам узлов, которые вы найдете через XPath. Это обычно требует несколько больше строк кода, чем XmlDocument методы.

но: the XmlDocument и XmlNode классы реализуют IXPathNavigable, так что любой код, который вы пишете, чтобы использовать эти методы на XPathDocument также будет работать над XmlDocument. Если вы привыкнете писать против IXPathNavigable, ваши методы могут работать против какой-либо объект. (Вот почему с помощью XmlNode и XmlDocument в сигнатурах метода помечается FxCop.)

к сожалению, XDocument и XElementXNode и XObject) не реализовать IXPathNavigable.

еще одна вещь, не присутствующая в ответе nyxtom, - это XmlReader. Вы обычно используете XmlReader чтобы избежать накладных расходов на разбор XML-потока в объектную модель перед началом его обработки. Вместо этого, вы используете XmlReader для обработки входного потока по одному XML-узлу за раз. Это, по сути .Чистый ответ на саксофоне. Это позволяет писать очень быстрый код для обработки очень больших XML-документов.

XmlReader также предоставляет самый простой способ обработки фрагментов XML-документа, например поток XML-элементов без элемента encluding, который возвращает параметр SQL Server for XML RAW.

код, который вы пишете, используя XmlReader обычно очень тесно связан с форматом XML, который он читает. Использование XPath позволяет вашему коду быть гораздо, гораздо более свободно связанным с XML, поэтому это, как правило, правильный ответ. Но когда вам нужно использовать XmlReader, вы очень нужно.

прежде всего, познакомьтесь с новым XDocument и XElement классы, потому что они являются улучшением по сравнению с предыдущим семейством XmlDocument.

  1. они работают с LINQ
  2. они быстрее и легче

, возможно, Вам все еще придется использовать старые классы для работы с устаревшим кодом - особенно с ранее созданными прокси. В этом случае вам нужно будет ознакомиться с некоторыми шаблоны для взаимодействия между этими классами обработки XML.

Я думаю, что ваш вопрос довольно широк и потребует слишком много в одном ответе, чтобы дать детали, но это первый общий ответ, о котором я подумал, и служит началом.

101 Linq samples

http://msdn.microsoft.com/en-us/library/bb387098.aspx

и Linq to XML samples

http://msdn.microsoft.com/en-us/vbasic/bb688087.aspx

и я думаю, что Linq упрощает XML.

Если вы работаете в .NET 3.5 и не боитесь экспериментального кода, Вы можете проверить LINQ to XSD (http://blogs.msdn.com/xmlteam/archive/2008/02/21/linq-to-xsd-alpha-0-2.aspx), который будет генерировать классы .NET из XSD (включая встроенные правила из XSD).

затем он имеет возможность записывать прямо в файл и читать из файла, гарантируя, что он соответствует правилам XSD.

Я определенно предлагаю иметь XSD для любого XML документ, с которым вы работаете:

  • позволяет применять правила в XML
  • позволяет другим видеть, как XML/ будет структурирован
  • может использоваться для проверки XML

Я считаю, что Liquid XML Studio-отличный инструмент для создания XSD, и это бесплатно!

Если вы создаете типизированный набор данных в конструкторе, то вы автоматически получаете xsd, строго типизированный объект, и можете загружать и сохранять xml с одной строкой кода.

мое личное мнение, как программиста на C#, заключается в том, что лучший способ справиться с XML в C# - это делегировать эту часть кода в проект VB .NET. В .NET 3.5 VB .NET имеет XML-литералы, которые делают работу с XML гораздо более интуитивной. Смотрите здесь, например:

обзор LINQ to XML в Visual Basic

(обязательно установите страницу для отображения кода VB, а не кода C#.)

Я бы написал остальную часть проекта на C#, но обрабатывать XML в a ссылается на проект VB.

запись XML с помощью класса XmlDocument

//itemValues is collection of items in Key value pair format
//fileName i name of XML file which to creatd or modified with content
    private void WriteInXMLFile(System.Collections.Generic.Dictionary<string, object> itemValues, string fileName)
    {
        string filePath = "C:\\tempXML\" + fileName + ".xml";
        try
        {

            if (System.IO.File.Exists(filePath))
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(filePath);                   

                XmlNode rootNode = doc.SelectSingleNode("Documents");

                XmlNode pageNode = doc.CreateElement("Document");
                rootNode.AppendChild(pageNode);


                foreach (string key in itemValues.Keys)
                {

                    XmlNode attrNode = doc.CreateElement(key);
                    attrNode.InnerText = Convert.ToString(itemValues[key]);
                    pageNode.AppendChild(attrNode);
                    //doc.DocumentElement.AppendChild(attrNode);

                }
                doc.DocumentElement.AppendChild(pageNode);
                doc.Save(filePath);
            }
            else
            {
                XmlDocument doc = new XmlDocument();
                using(System.IO.FileStream fs = System.IO.File.Create(filePath))
                {
                    //Do nothing
                }

                XmlNode rootNode = doc.CreateElement("Documents");
                doc.AppendChild(rootNode);
                doc.Save(filePath);

                doc.Load(filePath);

                XmlNode pageNode = doc.CreateElement("Document");
                rootNode.AppendChild(pageNode);

                foreach (string key in itemValues.Keys)
                {                          
                    XmlNode attrNode = doc.CreateElement(key);                           
                    attrNode.InnerText = Convert.ToString(itemValues[key]);
                    pageNode.AppendChild(attrNode);
                    //doc.DocumentElement.AppendChild(attrNode);

                }
                doc.DocumentElement.AppendChild(pageNode);

                doc.Save(filePath);

            }
        }
        catch (Exception ex)
        {

        }

    }

OutPut look like below
<Dcouments>
    <Document>
        <DocID>01<DocID>
        <PageName>121<PageName>
        <Author>Mr. ABC<Author>
    <Dcoument>
    <Document>
        <DocID>02<DocID>
        <PageName>122<PageName>
        <Author>Mr. PQR<Author>
    <Dcoument>
</Dcouments>

nyxtom,

Не Должны ли" doc "и" xdoc " совпадать в Примере 1?

XDocument **doc** = XDocument.Load(pathToXml);
List<Person> people = (from xnode in **xdoc**.Element("People").Elements("Person")
                   select new Person
                   {
                       Name = xnode.Attribute("Name").Value
                   }).ToList();

ответ куки хорош... но вот подробные инструкции о том, как создать строго типизированный объект из XSD(или XML) и сериализовать/десериализовать в нескольких строках кода:

- инструкции

Если вам когда-нибудь понадобится конвертировать данные между XmlNode XNode XElement
(например, для использования LINQ) эти расширения могут быть полезны для вас:

public static class MyExtensions
{
    public static XNode GetXNode(this XmlNode node)
    {
        return GetXElement(node);
    }

    public static XElement GetXElement(this XmlNode node)
    {
        XDocument xDoc = new XDocument();
        using (XmlWriter xmlWriter = xDoc.CreateWriter())
            node.WriteTo(xmlWriter);
        return xDoc.Root;
    }

    public static XmlNode GetXmlNode(this XElement element)
    {
        using (XmlReader xmlReader = element.CreateReader())
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlReader);
            return xmlDoc;
        }
    }

    public static XmlNode GetXmlNode(this XNode node)
    {
        return GetXmlNode(node);
    }
}

использование:

XmlDocument MyXmlDocument = new XmlDocument();
MyXmlDocument.Load("MyXml.xml");
XElement MyXElement = MyXmlDocument.GetXElement(); // Convert XmlNode to XElement
List<XElement> List = MyXElement.Document
   .Descendants()
   .ToList(); // Now you can use LINQ
...

Comments

    Ничего не найдено.