C # 2.0'da XML belgeleri, XSD vb. İle başa çıkmanın en iyi yolu nedir?
Hangi sınıfların kullanılacağı vb. XML belgelerini ayrıştırmanın ve oluşturmanın en iyi uygulamaları nelerdir?
DÜZENLEME: .Net 3.5 önerileri de açığız.
C # 2.0'da XML belgeleri, XSD vb. İle başa çıkmanın en iyi yolu nedir?
Hangi sınıfların kullanılacağı vb. XML belgelerini ayrıştırmanın ve oluşturmanın en iyi uygulamaları nelerdir?
DÜZENLEME: .Net 3.5 önerileri de açığız.
Yanıtlar:
C # 2.0'da birincil okuma ve yazma yöntemi, XmlDocument sınıfı aracılığıyla yapılır . Ayarlarınızın çoğunu, kabul ettiği XmlReader aracılığıyla doğrudan XmlDocument'e yükleyebilirsiniz.
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);
Bir XML belgesini okumanın en kolay / en hızlı yolunu XPath kullanmaktır.
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");
Bir XML belgesini doğrulamak için XSD belgeleriyle çalışmanız gerekiyorsa, bunu kullanabilirsiniz.
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();
(GÜNCELLEME 1)
.NET 3.5'te, benzer görevleri gerçekleştirmek için XDocument kullanırsınız. Ancak fark, ihtiyacınız olan kesin verileri seçmek için Linq Sorguları gerçekleştirme avantajına sahip olmanızdır. Nesne başlatıcıların eklenmesiyle, kendi tanımınıza ait nesneleri doğrudan sorgunun içinde döndüren bir sorgu oluşturabilirsiniz.
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();
(GÜNCELLEME 2)
NET 3.5'te XML oluşturmak için XDocument'ı kullanmanın güzel bir yolu aşağıdadır. Bu, kodun istenen çıktıya benzer bir modelde görünmesini sağlar.
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")
)
)
);
oluşturur
<!--Xml Document-->
<catalog>
<book id="bk001">
<title>Book Title</title>
</book>
</catalog>
Her şey başarısız olursa, burada tartıştığım birçok örneği ve daha fazlasını içeren bu MSDN makalesine göz atabilirsiniz. http://msdn.microsoft.com/en-us/library/aa468556.aspx
Boyuta bağlıdır; küçük ila orta boyutlu xml için, XmlDocument (herhangi bir C # /. NET sürümleri) veya XDocument (.NET 3.5 / C # 3.0) gibi bir DOM bariz bir şekilde kazanır. Xsd kullanmak için, Sen xml bir kullanarak yükleyebilirsiniz XmlReader ve bir XmlReader (için kabul eder oluşturun bir) XmlReaderSettings . XmlReaderSettings nesneleri, xsd (veya dtd) doğrulaması gerçekleştirmek için kullanılabilen bir Schemas özelliğine sahiptir.
Xml yazmak için, LINQ-to-XML (XDocument) ile içerik düzenlemenin eski XmlDocument'e göre biraz daha kolay olduğunu belirterek, aynı şeyler geçerlidir.
Ancak, büyük xml için bir DOM çok fazla belleği parçalayabilir, bu durumda doğrudan XmlReader / XmlWriter kullanmanız gerekebilir.
Son olarak, xml'yi işlemek için XslCompiledTransform'u (bir xslt katmanı) kullanmak isteyebilirsiniz .
Xml ile çalışmanın alternatifi, bir nesne modeliyle çalışmaktır; xsd.exe'yi , xsd uyumlu bir modeli temsil eden sınıflar oluşturmak için kullanabilir ve xml'yi nesneler olarak yükleyebilir, OO ile işleyebilir ve sonra bu nesneleri yeniden serileştirebilirsiniz; bunu XmlSerializer ile yaparsınız .
nyxtom'un cevabı çok güzel. Ona birkaç şey eklerim:
Bir XML belgesine salt okunur erişime ihtiyacınız varsa XPathDocument, bu çok daha hafif bir nesnedir XmlDocument.
Kullanmanın dezavantajı XPathDocument, tanıdık SelectNodesve SelectSingleNodeyöntemlerini kullanamamanızdır XmlNode. Bunun yerine, aşağıdakilerin IXPathNavigablesağladığı araçları kullanmanız CreateNavigatorgerekir: bir oluşturmak için XPathNavigatorkullanın ve XPath aracılığıyla bulduğunuz düğüm listeleri üzerinde yineleme XPathNavigatoryapmak için XPathNodeIterators oluşturmak için kullanın . Bu genellikle XmlDocumentyöntemlerden birkaç satır daha fazla kod gerektirir .
Ancak: XmlDocumentve XmlNodesınıfları uygulanır IXPathNavigable, bu nedenle bu yöntemleri kullanmak için yazdığınız herhangi bir kod XPathDocument, bir XmlDocument. Karşı yazmaya alışırsanız IXPathNavigable, yöntemleriniz her iki nesneye karşı da çalışabilir. ( Yöntem imzalarının kullanılması XmlNodeve kullanılmasının XmlDocumentFxCop tarafından işaretlenmesinin nedeni budur .)
Ne yazık, XDocumentve XElement(ve XNodeve XObject) uygulamak gerekmez IXPathNavigable.
Nyxtom'un cevabında bulunmayan başka bir şey de XmlReader. Genellikle XmlReaderXML akışını işlemeye başlamadan önce bir nesne modeline ayrıştırmanın ek yükünden kaçınmak için kullanırsınız . Bunun yerine, XmlReadergiriş akışını her seferinde bir XML düğümü işlemek için bir kullanırsınız . Bu esasen .NET'in SAX'e cevabıdır. Çok büyük XML belgelerini işlemek için çok hızlı kod yazmanıza olanak tanır.
XmlReader ayrıca XML belge parçalarını işlemenin en basit yolunu sağlar, örneğin, SQL Server'ın FOR XML RAW seçeneğinin döndürdüğü kapsayıcı öğe olmadan XML öğelerinin akışı.
Kullanarak yazdığınız kod XmlReader, genellikle okuduğu XML formatına çok sıkı bir şekilde bağlıdır. XPath kullanmak, kodunuzun XML ile çok daha gevşek bir şekilde eşleşmesine izin verir, bu yüzden genellikle doğru cevaptır. Ancak kullanmanız gerektiğinde XmlReader, gerçekten buna ihtiyacınız var.
XPathNavigator CreateNavigator(this XNode node)Bir XPathNavigatorden XNode(türetilmiş sınıfı içeren XDocument) oluşturmak için bir uzantı yöntemi olduğunu unutmayın .
Her şeyden önce, yeni XDocument ve XElement sınıflarını tanıyın , çünkü bunlar önceki XmlDocument ailesine göre bir gelişme.
Ancak , eski kodla, özellikle önceden oluşturulmuş proxy'lerle çalışmak için yine de eski sınıfları kullanmanız gerekebilir. Bu durumda, bu XML işleme sınıfları arasında birlikte çalışmak için bazı kalıplara aşina olmanız gerekecektir.
Sorunuzun oldukça geniş olduğunu ve ayrıntı vermek için tek bir cevapta çok fazla şey gerektireceğini düşünüyorum, ancak bu aklıma gelen ilk genel cevap ve başlangıç olarak hizmet ediyor.
101 Linq örnekleri
http://msdn.microsoft.com/en-us/library/bb387098.aspx
ve Linq - XML örnekleri
http://msdn.microsoft.com/en-us/vbasic/bb688087.aspx
Ve Linq'in XML'i kolaylaştırdığını düşünüyorum.
.NET 3.5'te çalışıyorsanız ve deneysel koddan çekinmiyorsanız, LINQ to XSD'ye göz atabilirsiniz ( http://blogs.msdn.com/xmlteam/archive/2008/02/21/linq-to- xsd-alpha-0-2.aspx ) bir XSD'den .NET sınıfları oluşturacaktır ( XSD'deki yerleşik kurallar dahil).
Daha sonra, doğrudan bir dosyaya yazma ve bir dosyadan okuma, XSD kurallarına uyduğundan emin olma yeteneğine sahiptir.
Çalıştığınız herhangi bir XML belgesi için kesinlikle bir XSD'ye sahip olmanızı öneririm:
Liquid XML Studio'nun XSD'ler oluşturmak için harika bir araç olduğunu düşünüyorum ve ücretsiz!
XmlDocument sınıfıyla XML yazma
//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>
Tasarımcıda yazılı bir veri kümesi oluşturursanız, otomatik olarak bir xsd, güçlü yazılmış bir nesne alırsınız ve xml'yi bir satır kodla yükleyebilir ve kaydedebilirsiniz.
Bir C # programcısı olarak benim kişisel fikrim, C # 'da XML ile başa çıkmanın en iyi yolunun, kodun bu bölümünü bir VB .NET projesine devretmek olduğudur. .NET 3.5'te, VB .NET, XML ile uğraşmayı çok daha sezgisel hale getiren XML Literals'e sahiptir. Örneğin buraya bakın:
Visual Basic'te LINQ to XML'e genel bakış
(Sayfayı C # kodunu değil, VB kodunu gösterecek şekilde ayarladığınızdan emin olun.)
Projenin geri kalanını C # ile yazardım, ancak başvurulan bir VB projesinde XML'i ele alırdım.
Nyxtom,
Örnek 1'deki "doc" ve "xdoc" eşleşmemeli mi?
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();
Cookey'nin cevabı güzel ... ancak işte bir XSD'den (veya XML) güçlü bir şekilde yazılmış bir nesnenin nasıl oluşturulacağına ve birkaç satır kodda serileştirme / seriyi kaldırma hakkında ayrıntılı talimatlar:
Verileri XmlNode<=> XNode<=> arasında dönüştürmeniz gerekirse XElement
(örneğin, LINQ kullanmak için) bu Uzantılar sizin için yararlı olabilir:
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);
}
}
Kullanım:
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
...