วิธีแยกวิเคราะห์ไฟล์ XML หนึ่งไฟล์ [ปิด]


492

มีวิธีง่าย ๆ ในการแยกวิเคราะห์ไฟล์ XML ใน C # หรือไม่? ถ้าเป็นเช่นนั้นอะไร


คุณสามารถใช้การดำเนินการนี้: stackoverflow.com/a/34813985/5784646
Eulogy

ตกลงฉันเปิดใหม่นี้ ซ้ำกันเป็นวิธีแก้ปัญหาของเครื่องอ่าน XML ซึ่งเป็นเรื่องเกี่ยวกับการแยกวิเคราะห์ไฟล์ XML posssible ซ้ำกันสามารถเห็นได้ในคำถามที่แก้ไขประวัติ PS @GeorgeStocker
เจเรมี ธ อมป์สัน

1
@JeremyThompson หนึ่งในเหตุผลที่สิ่งนี้ซ้ำซ้อนคือคำถามอื่นมีคำตอบที่ดีกว่ามาก คำตอบยอดนิยมเป็นคำตอบ "ลิงก์เท่านั้น" ที่เรียบง่ายไม่มีประโยชน์
George Stocker

1
@GeorgeStocker คำถามนั้นแตกต่างกันพอที่จะอยู่ร่วมกันและทั้งคู่ก็มีคำตอบที่ยอดเยี่ยมรวมถึงคำถามที่ได้รับการยอมรับกำลังใช้เทคโนโลยีที่แตกต่างกัน นั่นเป็นเหตุผลที่ผมลงคะแนนที่เราจะออกนี้เปิดฉันรู้ว่านี้ได้รับการยอมรับอย่างใดอย่างหนึ่งคือการเชื่อมโยงเท่านั้น แต่มันเป็น MSDN และเขียนในช่วงเวลาก่อนหน้านั้นเป็นที่ยอมรับไม่ได้หวังว่าผลข้างเคียงของการเปิดเป็นเชียร์จอนขึ้นเล็กน้อยอ่านรายละเอียดของเขา อย่างไรก็ตามเสียงเชียร์
Jeremy Thompson

คำตอบ:



314

มันง่ายมาก ฉันรู้ว่านี่เป็นวิธีมาตรฐาน แต่คุณสามารถสร้างห้องสมุดของคุณเองเพื่อจัดการกับสิ่งที่ดีกว่า

นี่คือตัวอย่างบางส่วน:

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

นอกจากนี้ยังมีวิธีการอื่น ๆ ในการทำงานกับ ยกตัวอย่างเช่นที่นี่ และฉันคิดว่าไม่มีวิธีที่ดีที่สุดในการทำเช่นนี้ คุณต้องเลือกด้วยตัวเองเสมอสิ่งที่เหมาะสมที่สุดสำหรับคุณ


47
+1 สำหรับการกล่าวถึง XmlDocument ซึ่งสะดวกกว่าอินเตอร์เฟซการทำให้เป็นอนุกรมในบางกรณี หากคุณอยู่หลังองค์ประกอบหนึ่งคุณสามารถเข้าถึงองค์ประกอบย่อยด้วยตัวทำดัชนี: xmlDoc ["Root"] และสิ่งเหล่านี้สามารถถูกโยงโซ่: xmlDoc ["Root"] ["โฟลเดอร์"] ["รายการ"] เพื่อขุดลง ลำดับชั้น (แม้ว่ามันจะเป็นเรื่องที่เหมาะสมที่จะตรวจสอบว่าองค์ประกอบเหล่านี้มีอยู่จริง)
เจสันวิลเลียมส์

1
InnerTextที่นี่รับค่าของโหนดนั้นต่อกันกับค่าทั้งหมดของโหนดลูก - ใช่ไหม? ดูเหมือนว่าเป็นเรื่องแปลกที่ต้องการ
Don Cheadle

17
โปรแกรมเมอร์ที่มีรายชื่อเพื่อนผู้หญิง? Shenanigans!
E. van Putten

1
@ E.vanPutten ไม่ได้อยู่ในยุคนี้ นี่ไม่ใช่ Revenge of the Nerds
4052054

@ DonCheadle หากคุณไม่ได้คาดหวังว่าจะมีโหนดลูกใด ๆ จากนั้นก็InnerTextจะส่งกลับค่าโหนด - ซึ่งเป็นสิ่งที่ฉัน (และคนอื่นอาจอ่านคำถามนี้) ฉันกำลังแยกวิเคราะห์ XML เพื่อค้นหาในสถานที่แรก
F1Krazy

48

ใช้XSD Schemaที่ดีเพื่อสร้างชุดคลาสที่มีxsd.exeและใช้XmlSerializerเพื่อสร้างแผนผังวัตถุจาก XML ของคุณและในทางกลับกัน หากคุณมีข้อ จำกัด เล็กน้อยในโมเดลของคุณคุณสามารถลองสร้างการแม็พโดยตรงระหว่างคลาสโมเดลของคุณกับ XML ด้วยแอ็ตทริบิวต์ Xml *

มีบทความเบื้องต้นเกี่ยวกับ XML Serializationบน MSDN

เคล็ดลับประสิทธิภาพ: การสร้างและXmlSerializerราคาแพง อ้างอิงกับXmlSerializerอินสแตนซ์ของคุณหากคุณต้องการแยก / เขียนไฟล์ XML หลายไฟล์



5
ตัวอย่างที่ดีคือ "ตัวอย่างใบสั่งซื้อ" ที่อยู่ตรงกลางของตัวอย่างนี้จาก microsoft msdn.microsoft.com/en-us/library/58a18dwa.aspx คุณหลีกเลี่ยงการสร้างสคีมา - คลาส c # ของคุณคือสคีมาที่ประดับด้วยแอตทริบิวต์ C #
Mark Lakata

25

หากคุณกำลังประมวลผลข้อมูลจำนวนมาก (หลายเมกะไบต์) คุณต้องใช้XmlReaderเพื่อสตรีมแยกวิเคราะห์ XML

สิ่งอื่น ( XPathNavigator, XElement, XmlDocumentและแม้กระทั่งXmlSerializerถ้าคุณให้เต็มรูปแบบกราฟวัตถุที่สร้างขึ้น) จะส่งผลให้การใช้งานหน่วยความจำสูงและยังมีเวลาในการโหลดช้ามาก

แน่นอนถ้าคุณต้องการข้อมูลทั้งหมดในหน่วยความจำอย่างไรก็ตามคุณอาจไม่มีทางเลือกมากนัก


18

การใช้งานXmlTextReader, XmlReader, XmlNodeReaderและSystem.Xml.XPathnamespace และ ( XPathNavigator, XPathDocument, XPathExpression, XPathnodeIterator)

มักจะXPathทำให้การอ่าน XML ง่ายขึ้นซึ่งเป็นสิ่งที่คุณอาจมองหา


2
FYI, คุณไม่ควรใช้หรือnew XmlTextReader() new XmlTextWriter()พวกเขาเลิกใช้แล้วตั้งแต่. NET 2.0 ใช้XmlReader.Create()หรือXmlWriter.Create()แทน
John Saunders

10

ฉันเพิ่งได้รับการร้องขอให้ทำงานกับแอปพลิเคชันที่เกี่ยวข้องกับการแยกวิเคราะห์เอกสาร XML และฉันเห็นด้วยกับ Jon Galloway ว่าวิธีการที่ใช้ LINQ เป็น XML นั้นเป็นสิ่งที่ดีที่สุด อย่างไรก็ตามฉันต้องขุดเล็กน้อยเพื่อหาตัวอย่างที่ใช้งานได้ดังนั้นโดยไม่ต้องกังวลใจต่อไปนี่คือบางส่วน!

ความคิดเห็นใด ๆ ยินดีต้อนรับเป็นรหัสนี้ใช้งานได้ แต่อาจไม่สมบูรณ์และฉันต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการแยกวิเคราะห์ XML สำหรับโครงการนี้!

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

ด้วยฟังก์ชั่นเหล่านี้ฉันสามารถแยกองค์ประกอบและคุณลักษณะใด ๆ จากไฟล์ XML ได้โดยไม่มีปัญหา!


8

หากคุณกำลังใช้ NET 2.0 ลองXmlReaderและ subclasses ของตนและXmlTextReader XmlValidatingReaderพวกเขามีวิธีที่รวดเร็วน้ำหนักเบา (การใช้หน่วยความจำ ฯลฯ ), ไปข้างหน้าอย่างเดียวในการแยกไฟล์ XML

หากคุณต้องการความสามารถในการลองXPath หากคุณต้องการเอกสารทั้งหมดในหน่วยความจำลองXPathNavigatorXmlDocument


7

นอกจากนี้คุณสามารถใช้ตัวเลือก XPath ด้วยวิธีต่อไปนี้ (วิธีง่าย ๆ ในการเลือกโหนดที่ระบุ):

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

เอกสารประกอบ


6

ฉันไม่แน่ใจว่ามี "แนวปฏิบัติที่ดีที่สุดสำหรับการแยกวิเคราะห์ XML" หรือไม่ มีเทคโนโลยีมากมายที่เหมาะกับสถานการณ์ที่แตกต่างกัน วิธีการใช้งานขึ้นอยู่กับสถานการณ์ที่เป็นรูปธรรม

คุณสามารถไปกับLINQ กับ XML , XmlReader, XPathNavigatorหรือแม้กระทั่งการแสดงออกปกติ หากคุณอธิบายความต้องการของคุณฉันสามารถลองให้คำแนะนำได้


3
regex สำหรับ xml คุณสัตว์ประหลาด
จะ

3

คุณสามารถแยกวิเคราะห์ XML โดยใช้ไลบรารีSystem.Xml.Linqนี้ ด้านล่างเป็นตัวอย่างรหัสที่ฉันใช้ในการแยกวิเคราะห์ไฟล์ 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

คุณสามารถใช้ExtendedXmlSerializerเพื่อทำให้เป็นอนุกรมและดีซีเรียลไลซ์

การ ติดตั้งคุณสามารถติดตั้ง ExtendedXmlSerializer จากnugetหรือเรียกใช้คำสั่งต่อไปนี้:

Install-Package ExtendedXmlSerializer

อันดับ:

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

ซีเรียลไลซ์

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

Serializer XML มาตรฐานใน. NET มีข้อ จำกัด มาก

  • ไม่สนับสนุนการทำให้เป็นอนุกรมของคลาสที่มีการอ้างอิงแบบวงกลมหรือคลาสที่มีคุณสมบัติอินเตอร์เฟส
  • ไม่รองรับพจนานุกรม
  • ไม่มีกลไกในการอ่าน XML เวอร์ชันเก่า
  • ถ้าคุณต้องการสร้าง serializer ที่กำหนดเองคลาสของคุณต้องสืบทอดจาก IXmlSerializable ซึ่งหมายความว่าคลาสของคุณจะไม่เป็นคลาส POCO
  • ไม่รองรับ IoC

ExtendedXmlSerializer สามารถทำสิ่งนี้และอีกมากมาย

ExtendedXmlSerializer สนับสนุน.NET 4.5หรือสูงกว่าและ.NET หลัก คุณสามารถรวมเข้ากับ WebApi และ AspCore


1

คุณสามารถใช้ XmlDocument และสำหรับจัดการหรือดึงข้อมูลจากแอ็ตทริบิวต์ที่คุณสามารถคลาส Linq ไปยัง XML

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.