Каков наилучший способ работы с документами XML, XSD и т.д. в С# 2.0?
Какие классы использовать и т.д. Каковы наилучшие методы анализа и создания XML-документов и т.д.
РЕДАКТИРОВАТЬ:.Net 3.5 также приветствуются.
Каков наилучший способ работы с документами XML, XSD и т.д. в С# 2.0?
Какие классы использовать и т.д. Каковы наилучшие методы анализа и создания XML-документов и т.д.
РЕДАКТИРОВАТЬ:.Net 3.5 также приветствуются.
Основные средства чтения и записи в С# 2.0 выполняются с помощью класса XmlDocument. Вы можете загрузить большинство своих настроек непосредственно в XmlDocument через XmlReader, который он принимает.
XmlDocument document = new XmlDocument();
document.LoadXml("<People><Person Name='Nick' /><Person Name='Joe' /></People>");
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.
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-документа, вы можете использовать это.
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); }
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
}
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 (любые версии С#/. NET) или XDocument (.NET 3.5/С# 3.0) является очевидным победителем. Для использования xsd вы можете загрузить xml с помощью XmlReader, и XmlReader принимает (to Create) a XmlReaderSettings. Объекты XmlReaderSettings имеют свойство Schemas, которое может использоваться для проверки 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
для создания XPathNodeIterator
для перебора списков узлов, которые вы найдете через XPath. Обычно это требует еще нескольких строк кода, чем методы XmlDocument
.
Но: классы XmlDocument
и XmlNode
реализуют IXPathNavigable
, поэтому любой код, который вы пишете для использования этих методов в XPathDocument
, также будет работать на XmlDocument
. Если вы привыкли писать против IXPathNavigable
, ваши методы могут работать против любого объекта. (Вот почему использование XmlNode
и XmlDocument
в сигнатурах метода помечено FxCop.)
С сожалением, XDocument
и XElement
(и XNode
и XObject
) не реализуют IXPathNavigable
.
Еще одна вещь, отсутствующая в nyxtom ответе, - XmlReader
. Обычно вы используете XmlReader
, чтобы избежать накладных расходов на синтаксический анализ XML-потока в объектной модели до того, как вы начнете его обрабатывать. Вместо этого вы используете XmlReader
для обработки входного потока один XML node за раз. Это, по сути,.NET ответ на SAX. Это позволяет писать очень быстрый код для обработки очень больших XML-документов.
XmlReader
также обеспечивает простейший способ обработки фрагментов документа XML, например. поток элементов XML без элемента, который возвращает параметр SQL Server FOR XML RAW.
Код, который вы пишете с помощью XmlReader
, как правило, очень тесно связан с форматом прочитанного XML. Использование XPath позволяет вашему коду быть намного, гораздо более слабо связан с XML, поэтому он, как правило, правильный ответ. Но когда вам нужно использовать XmlReader
, вам это действительно нужно.
101 образцов Linq
http://msdn.microsoft.com/en-us/library/bb387098.aspx
и Примеры Linq для XML
http://msdn.microsoft.com/en-us/vbasic/bb688087.aspx
И я думаю, что Linq упрощает XML.
Прежде всего, ознакомьтесь с новыми классами XDocument и XElement, поскольку они являются улучшением по сравнению с предыдущим семейством XmlDocument.
Тем не менее, вам, возможно, придется использовать старые классы для работы с устаревшим кодом - особенно с предварительно созданными прокси. В этом случае вам нужно будет ознакомиться с некоторыми шаблонами для взаимодействия между этими классами обработки XML.
Я думаю, что ваш вопрос довольно широк и потребует слишком многого в одном ответе, чтобы дать подробности, но это первый общий ответ, который я думал, и служит началом.
Если вы работаете в .NET 3.5, и вы не боитесь экспериментального кода, вы можете проверить LINQ на XSD (http://blogs.msdn.com/xmlteam/archive/2008/02/21/linq-to-xsd-alpha-0-2.aspx), который будет генерировать .NET-классы из XSD (включая встроенные правила из XSD).
Затем он имеет возможность писать прямо в файл и читать из файла, гарантируя, что он соответствует правилам XSD.
Я определенно предлагаю иметь XSD для любого документа XML, с которым вы работаете:
Я нахожу, что Liquid XML Studio - отличный инструмент для создания XSD, и он бесплатный!
Если вы создаете типизированный набор данных в дизайнере, вы автоматически получаете xsd, строго типизированный объект и можете загружать и сохранять xml с одной строкой кода.
Мое личное мнение, как программист на С#, заключается в том, что лучший способ справиться с XML в С# - делегировать эту часть кода проекту VB.NET. В .NET 3.5 VB.NET имеет XML-литералы, которые делают работу с XML более интуитивной. См. Здесь, например:
Обзор LINQ to XML в Visual Basic
(Обязательно установите страницу для отображения кода VB, а не кода С#.)
Я бы написал остальную часть проекта в С#, но обработал XML в проекте 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>
Ответ на куки хороший... но вот подробные инструкции о том, как создать строго типизированный объект из XSD (или XML) и сериализовать/десериализовать в нескольких строках кода:
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();