XML dosyaları nasıl ayrıştırılır? [kapalı]


492

C # XML dosyalarını ayrıştırma basit bir yöntemi var mı? Öyleyse ne olmuş?


Bu uygulamayı kullanabilirsiniz: stackoverflow.com/a/34813985/5784646
Eulogy

Tamam, bunu tekrar açtım. Yinelenen, XML dosyalarını çözümlemede olduğu gibi bir XML Okuyucu çözümü idi. Olası yinelenen sorular düzenleme geçmişinde görülebilir ps @GeorgeStocker
Jeremy Thompson

1
@JeremyThompson Bunun kopya olmasının nedenlerinden biri, diğer sorunun çok daha iyi bir cevabı olması. En önemli cevap basit bir "sadece bağlantı" cevabı olmak yararlı değildir.
George Stocker

1
@GeorgeStocker sorular birlikte var olacak kadar farklıdır ve her ikisinin de harika cevapları vardır, ayrıca kabul edilenler farklı teknolojiler kullanmaktadır. Bu yüzden bunu açık bıraktığımıza oy verdim, bu kabul edilenin sadece bağlantı olduğunu biliyorum, ancak MSDN ve kabul edilemez bir zaman önce yazılmıştı, umarım yeniden açmanın bir yan etkisi Jon'u biraz neşelendirir , profilini okuyun . Neyse şerefe.
Jeremy Thompson

Yanıtlar:



314

Çok basit. Bunların standart yöntemler olduğunu biliyorum, ancak bununla daha iyi başa çıkmak için kendi kütüphanenizi oluşturabilirsiniz.

İşte bazı örnekler:

XmlDocument xmlDoc= new XmlDocument(); // Create an XML document object
xmlDoc.Load("yourXMLFile.xml"); // Load the XML document from the specified file

// Get elements
XmlNodeList girlAddress = xmlDoc.GetElementsByTagName("gAddress");
XmlNodeList girlAge = xmlDoc.GetElementsByTagName("gAge"); 
XmlNodeList girlCellPhoneNumber = xmlDoc.GetElementsByTagName("gPhone");

// Display the results
Console.WriteLine("Address: " + girlAddress[0].InnerText);
Console.WriteLine("Age: " + girlAge[0].InnerText);
Console.WriteLine("Phone Number: " + girlCellPhoneNumber[0].InnerText);

Ayrıca, çalışmak için başka yöntemler de vardır. Örneğin, burada . Ve bence bunu yapmanın en iyi yolu yok; her zaman kendiniz seçmeniz gerekir, sizin için en uygun olanı.


47
Bazı durumlarda serileştirme arabirimlerinden çok daha uygun olan XmlDocument'ten bahsetmek için +1. Belirli bir öğenin peşindeyseniz, alt öğelere dizinleyici ile erişebilirsiniz: xmlDoc ["Root"] ve bunlar zincirlenebilir: xmlDoc ["Root"] ["Folder"] ["Item"] hiyerarşi (bu öğelerin gerçekten var olduğunu doğrulamak mantıklı olsa da)
Jason Williams

1
InnerTextBurada alt düğümlerin tüm değerleriyle birleştirilen bu düğümün değerini alır - değil mi? İstemek garip bir şey gibi görünüyor.
Don Cheadle

17
Bayan arkadaş listesi olan bir programcı mı? Maskaralık!
E. van Putten

1
@ E.vanPutten bugün ve yaşta değil. Bu
İnekler

@DonCheadle Eğer herhangi bir alt düğüm olmasını beklemiyorsanız , o InnerTextzaman sadece düğüm değerini döndürür.
F1Krazy

48

Xsd.exe ile bir sınıf kümesi oluşturmak için iyi bir XSD Şeması kullanın veXmlSerializer siz de onların XML ve yardımcısı bir nesne ağacı dışarı oluşturun. Modelinizde çok az kısıtlamanız varsa, Xml * Nitelikleri ile model sınıfları ve XML arasında doğrudan bir eşleme oluşturmayı bile deneyebilirsiniz.

Orada XML Serialization hakkında tanıtıcı bir makaleMSDN'de .

Performans ipucu: An oluşturmak XmlSerializerpahalıdır. XmlSerializerBirden fazla XML dosyasını ayrıştırmak / yazmak istiyorsanız örneğinize bir referans tutun .



5
Bunun iyi bir örneği, microsoft'un bu örneğinin ortasında yer alan "Satın Alma Siparişi Örneği" dir. msdn.microsoft.com/en-us/library/58a18dwa.aspx . Bir şema oluşturmak zorunda kalmazsınız - c # sınıfınız, C # öznitelikleriyle süslenmiş şemadır.
Mark Lakata

25

Büyük miktarda veri (çok megabayt) XmlReaderişliyorsanız, XML'yi ayrıştırmak için kullanmak istiyorsunuz .

(Başka bir şey XPathNavigator, XElement, XmlDocumenthatta ve XmlSerializertam oluşturulan nesne grafiği tutmak ise) neden olacaktır yüksek bellek kullanımı da çok yavaş bir yükleme süresini ve.

Tabii ki, yine de bellekteki tüm verilere ihtiyacınız varsa, o zaman fazla seçeneğiniz olmayabilir.



10

Kısa süre önce bir XML belgesinin ayrıştırılmasını içeren bir uygulama üzerinde çalışmam gerekiyordu ve Jon Galloway ile LINQ to XML tabanlı yaklaşımın bence en iyisi olduğunu kabul ediyorum. Ancak kullanılabilir örnekler bulmak için biraz kazmak zorunda kaldım, bu yüzden daha fazla uzatmadan, işte birkaç tane!

Bu kod çalışıyor gibi herhangi bir yorum hoş geldiniz ama mükemmel olmayabilir ve ben bu proje için XML ayrıştırma hakkında daha fazla bilgi edinmek istiyorum!

public void ParseXML(string filePath)  
{  
    // create document instance using XML file path
    XDocument doc = XDocument.Load(filePath);

    // get the namespace to that within of the XML (xmlns="...")
    XElement root = doc.Root;
    XNamespace ns = root.GetDefaultNamespace();

    // obtain a list of elements with specific tag
    IEnumerable<XElement> elements = from c in doc.Descendants(ns + "exampleTagName") select c;

    // obtain a single element with specific tag (first instance), useful if only expecting one instance of the tag in the target doc
    XElement element = (from c in doc.Descendants(ns + "exampleTagName" select c).First();

    // obtain an element from within an element, same as from doc
    XElement embeddedElement = (from c in element.Descendants(ns + "exampleEmbeddedTagName" select c).First();

    // obtain an attribute from an element
    XAttribute attribute = element.Attribute("exampleAttributeName");
}

Bu işlevler ile XML dosyasındaki herhangi bir öğeyi ve herhangi bir özniteliği ayrıştıramadım.


8

.NET 2.0 kullanıyorsanız, denemek XmlReaderve alt sınıfları XmlTextReaderve XmlValidatingReader. Bir XML dosyasını ayrıştırmak için hızlı, hafif (bellek kullanımı vb.) Yalnızca ileri bir yol sağlarlar.

XPathYeteneklere ihtiyacınız varsa XPathNavigator. Bellekteki tüm belgeye ihtiyacınız varsa deneyin XmlDocument.


7

Ek olarak, XPath seçicisini aşağıdaki şekilde kullanabilirsiniz (belirli düğümleri seçmenin kolay yolu):

XmlDocument doc = new XmlDocument();
doc.Load("test.xml");

var found = doc.DocumentElement.SelectNodes("//book[@title='Barry Poter']"); // select all Book elements in whole dom, with attribute title with value 'Barry Poter'

// Retrieve your data here or change XML here:
foreach (XmlNode book in nodeList)
{
  book.InnerText="The story began as it was...";
}

Console.WriteLine("Display XML:");
doc.Save(Console.Out);

Dökümantasyon


6

"XML ayrıştırmak için en iyi uygulama" olup olmadığından emin değilim. Farklı durumlar için çok sayıda teknoloji uygundur. Hangi yolun kullanılacağı somut senaryoya bağlıdır.

Sen gidebilirsiniz XML LINQ , XmlReader, XPathNavigatorhatta düzenli ifadeler. İhtiyaçlarınızı detaylandırırsanız, bazı önerilerde bulunmaya çalışabilirim.


3
xml için normal ifade. seni canavar.
will

3

Bu kitaplığı kullanarak XML'yi ayrıştırabilirsiniz System.Xml.Linq. Bir XML dosyasını ayrıştırmak için kullandığım örnek kod aşağıdadır

public CatSubCatList GenerateCategoryListFromProductFeedXML()
{
    string path = System.Web.HttpContext.Current.Server.MapPath(_xmlFilePath);

    XDocument xDoc = XDocument.Load(path);

    XElement xElement = XElement.Parse(xDoc.ToString());


    List<Category> lstCategory = xElement.Elements("Product").Select(d => new Category
    {
        Code = Convert.ToString(d.Element("CategoryCode").Value),
        CategoryPath = d.Element("CategoryPath").Value,
        Name = GetCateOrSubCategory(d.Element("CategoryPath").Value, 0), // Category
        SubCategoryName = GetCateOrSubCategory(d.Element("CategoryPath").Value, 1) // Sub Category
    }).GroupBy(x => new { x.Code, x.SubCategoryName }).Select(x => x.First()).ToList();

    CatSubCatList catSubCatList = GetFinalCategoryListFromXML(lstCategory);

    return catSubCatList;
}

1

Serileştirmek ve serisini kaldırmak için ExtendedXmlSerializer'ı kullanabilirsiniz .

Instalation ExtendedXmlSerializer'ı nuget'ten yükleyebilir veya aşağıdaki komutu çalıştırabilirsiniz:

Install-Package ExtendedXmlSerializer

Serile:

ExtendedXmlSerializer serializer = new ExtendedXmlSerializer();
var obj = new Message();
var xml = serializer.Serialize(obj);

deserialization

var obj2 = serializer.Deserialize<Message>(xml);

.NET'te standart XML Serializer çok sınırlıdır.

  • Dairesel referanslı sınıfın serileştirilmesini veya interface özelliğine sahip sınıfın desteklenmesini desteklemez,
  • Sözlükleri desteklemez,
  • XML'in eski sürümünü okumak için bir mekanizma yoktur,
  • Özel serileştirici oluşturmak istiyorsanız, sınıfınızın IXmlSerializable öğesinden devralması gerekir. Bu, sınıfınızın bir POCO sınıfı olmayacağı anlamına gelir,
  • IoC'yi desteklemez.

ExtendedXmlSerializer bunu ve çok daha fazlasını yapabilir.

ExtendedXmlSerializer .NET 4.5 veya üstünü ve .NET Core'u destekler . WebApi ve AspCore ile entegre edebilirsiniz.


1

XmlDocument kullanabilirsiniz ve özniteliklerden veri değiştirmek veya almak için Linq to XML sınıfları yapabilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.