Làm thế nào để phân tích các tệp XML? [đóng cửa]


492

Có một phương pháp đơn giản để phân tích tệp XML trong C # không? Nếu vậy thì sao?


bạn có thể sử dụng cách triển khai này: stackoverflow.com/a/34813985/5784646
Eulogy

Ok, tôi đã mở lại cái này. Bản sao là một giải pháp Trình đọc XML trong đó đây là về phân tích tệp XML. Bản sao sở hữu có thể được nhìn thấy trong lịch sử chỉnh sửa câu hỏi ps @GeorgeStocker
Jeremy Thompson

1
@JeremyThndry Một trong những lý do tại sao đây là một bản sao là câu hỏi khác có câu trả lời tốt hơn nhiều. Câu trả lời hàng đầu là một câu trả lời "chỉ liên kết" đơn giản là không hữu ích.
George Stocker

1
@GeorgeStocker các câu hỏi đủ khác nhau để cùng tồn tại và cả hai đều có câu trả lời tuyệt vời , cộng với những câu hỏi được chấp nhận đang sử dụng các công nghệ khác nhau. Đó là lý do tại sao tôi bỏ phiếu chúng tôi bỏ ngỏ điều này, tôi biết cái này được chấp nhận chỉ là liên kết nhưng nó là MSDN và được viết vào thời điểm trước đó là không thể chấp nhận được, hy vọng tác dụng phụ của việc mở lại là cổ vũ Jon một chút, đọc hồ sơ của anh ấy . Dù sao cũng cổ vũ.
Jeremy Thompson

Câu trả lời:



314

Nó rất đơn giản. Tôi biết đây là những phương pháp tiêu chuẩn, nhưng bạn có thể tạo thư viện của riêng mình để giải quyết vấn đề đó tốt hơn nhiều.

Dưới đây là một số ví dụ:

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);

Ngoài ra, có một số phương pháp khác để làm việc với. Ví dụ, ở đây . Và tôi nghĩ không có một phương pháp tốt nhất để làm điều này; bạn luôn cần phải chọn nó một mình, cái gì phù hợp nhất với bạn.


47
+1 để đề cập đến XmlDocument, tiện lợi hơn nhiều so với giao diện tuần tự hóa trong một số trường hợp. Nếu bạn theo sau một phần tử cụ thể, bạn có thể truy cập các phần tử con bằng trình chỉ mục: xmlDoc ["Root"] và các phần tử này có thể được xâu chuỗi: xmlDoc ["Root"] ["Thư mục"] ["Mục"] để tìm hiểu hệ thống phân cấp (mặc dù có thể xác thực rằng các yếu tố này thực sự tồn tại)
Jason Williams

1
InnerTextở đây có giá trị của nút đó, được nối với tất cả các giá trị của các nút con - phải không? Có vẻ như một điều kỳ lạ muốn.
Don Cheadle

17
Một lập trình viên với một danh sách bạn nữ? Thần thông!
E. van Putten

1
@ E.vanPutten không trong thời đại ngày nay. Đây không phải là Revenge of the Nerds
user4052054

@DonCheadle Nếu bạn không mong đợi đó để được bất kỳ nút con, sau đó InnerTextsẽ chỉ trả về giá trị nút - đó là những gì tôi (và có lẽ tất cả mọi người khác đọc câu hỏi này) đang phân tích cú pháp XML để tìm ở nơi đầu tiên.
F1Krazy

48

Sử dụng tốt Lược đồ XSD để tạo một tập hợp các lớp với xsd.exe và sử dụng một XmlSerializerđể tạo một cây đối tượng ra khỏi XML của bạn và ngược lại. Nếu bạn có một vài hạn chế đối với mô hình của mình, bạn thậm chí có thể thử tạo ánh xạ trực tiếp giữa các lớp mô hình và XML bằng các Thuộc tính Xml *.

một bài viết giới thiệu về Tuần tự hóa XML trên MSDN.

Mẹo hiệu suất: Xây dựng một XmlSerializerlà tốn kém. Giữ một tham chiếu đến XmlSerializerví dụ của bạn nếu bạn có ý định phân tích / ghi nhiều tệp XML.



5
Ví dụ điển hình là "Ví dụ đặt hàng mua" ở giữa ví dụ này từ microsoft. msdn.microsoft.com/en-us/l Library / 58a18dwa.aspx . Bạn tránh phải tạo một lược đồ - lớp c # của bạn là lược đồ, được trang trí bằng các thuộc tính C #.
Mark Lakata

25

Nếu bạn đang xử lý một lượng lớn dữ liệu (nhiều megabyte) thì bạn muốn sử dụng XmlReaderđể phân tích cú pháp XML.

Bất cứ điều gì khác ( XPathNavigator, XElement, XmlDocumentvà thậm chí XmlSerializernếu bạn giữ đồ thị đối tượng được tạo ra đầy đủ) sẽ cho kết quả trong sử dụng bộ nhớ cao và cũng là một thời gian tải rất chậm.

Tất nhiên, nếu bạn cần tất cả dữ liệu trong bộ nhớ, thì bạn có thể không có nhiều sự lựa chọn.


18

Sử dụng XmlTextReader, XmlReader, XmlNodeReadervà các System.Xml.XPathnamespace. Và ( XPathNavigator, XPathDocument, XPathExpression, XPathnodeIterator).

Thường XPathlàm cho việc đọc XML dễ dàng hơn, đó là những gì bạn có thể đang tìm kiếm.


2
FYI, bạn không nên sử dụng new XmlTextReader()hoặc new XmlTextWriter(). Chúng không được dùng nữa kể từ .NET 2.0. Sử dụng XmlReader.Create()hoặc XmlWriter.Create()thay thế.
John Saunders

10

Gần đây tôi đã được yêu cầu làm việc trên một ứng dụng liên quan đến phân tích cú pháp tài liệu XML và tôi đồng ý với Jon Galloway rằng cách tiếp cận dựa trên LINQ to XML là, theo tôi, là tốt nhất. Tuy nhiên tôi đã phải đào một ít để tìm các ví dụ có thể sử dụng được, vì vậy không cần phải quảng cáo thêm, đây là một vài!

Mọi ý kiến ​​đều được hoan nghênh vì mã này hoạt động nhưng có thể không hoàn hảo và tôi muốn tìm hiểu thêm về phân tích cú pháp XML cho dự án này!

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");
}

Với các hàm này, tôi có thể phân tích bất kỳ phần tử và thuộc tính nào từ tệp XML không có vấn đề gì cả!


8

Nếu bạn đang sử dụng .NET 2.0, hãy thử XmlReadervà các lớp con của nó XmlTextReaderXmlValidatingReader. Chúng cung cấp một cách nhanh chóng, nhẹ nhàng (sử dụng bộ nhớ, v.v.), cách chỉ chuyển tiếp để phân tích một tệp XML.

Nếu bạn cần XPathkhả năng, hãy thử XPathNavigator. Nếu bạn cần toàn bộ tài liệu trong bộ nhớ hãy thử XmlDocument.


7

Trong Bổ sung, bạn có thể sử dụng bộ chọn XPath theo cách sau (cách dễ dàng để chọn các nút cụ thể):

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);

tài liệu


6

Tôi không chắc liệu "thực hành tốt nhất để phân tích cú pháp XML" có tồn tại hay không. Có rất nhiều công nghệ phù hợp cho các tình huống khác nhau. Cách sử dụng phụ thuộc vào kịch bản cụ thể.

Bạn có thể đi với LINQ to XML , XmlReader, XPathNavigatorhoặc thậm chí biểu thức thông thường. Nếu bạn giải thích nhu cầu của mình, tôi có thể cố gắng đưa ra một số gợi ý.


3
regex cho xml. đồ quỷ.
sẽ

3

Bạn có thể phân tích cú pháp XML bằng thư viện này System.Xml.Linq. Dưới đây là mã mẫu tôi đã sử dụng để phân tích tệp XML

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

Bạn có thể sử dụng ExtendedXmlSerializer để tuần tự hóa và giải tuần tự hóa.

Instalation Bạn có thể cài đặt ExtendedXmlSerializer từ nuget hoặc chạy lệnh sau:

Install-Package ExtendedXmlSerializer

Tuần tự hóa:

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

Khử muối

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

Trình tuần tự XML tiêu chuẩn trong .NET rất hạn chế.

  • Không hỗ trợ tuần tự hóa lớp với tham chiếu tròn hoặc lớp có thuộc tính giao diện,
  • Không hỗ trợ Từ điển,
  • Không có cơ chế để đọc phiên bản cũ của XML,
  • Nếu bạn muốn tạo serializer tùy chỉnh, lớp của bạn phải kế thừa từ IXmlSerializable. Điều này có nghĩa là lớp của bạn sẽ không phải là lớp POCO,
  • Không hỗ trợ IoC.

ExtendedXmlSerializer có thể làm điều này và nhiều hơn nữa.

ExtendedXmlSerializer hỗ trợ .NET 4.5 trở lên và .NET Core . Bạn có thể tích hợp nó với WebApi và AspCore.


1

Bạn có thể sử dụng XmlDocument và để thao tác hoặc truy xuất dữ liệu từ các thuộc tính bạn có thể Linq sang các lớp XML.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.