XMLファイルはどのように解析されますか?[閉まっている]


492

C#でXMLファイルを解析する簡単な方法はありますか?もしそうなら、何ですか?


この実装を使用できます:stackoverflow.com/a/34813985/5784646
Eulogy

はい、再開しました。複製はXMLリーダーソリューションでしたが、これはXMLファイルの解析に関するものです。posssible重複は質問の中で見ることができます編集履歴PSの@GeorgeStocker
ジェレミー・トンプソン

1
@JeremyThompsonこれが重複していた理由の1つは、他の質問の方がはるかに優れた答えであるということです。上の答えは単純な「リンクのみ」の答えであるため、役に立ちません。
ジョージストッカー

1
@GeorgeStocker質問は、共存するのに十分なほど異なっており、両方とも素晴らしい答えを持っています。さらに、受け入れられた質問は異なるテクノロジーを使用しています。そのため、私はこれをオープンのままにしておくことに投票しました。これはリンクのみであることがわかっていますが、それはMSDNであり、それが受け入れられない以前に書かれたものです。とにかく乾杯。
ジェレミー・トンプソン

回答:



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
XmlDocumentについて言及する場合は+1。これは、場合によってはシリアル化インターフェイスよりもはるかに便利です。特定の要素の後にある場合は、インデクサー:xmlDoc ["Root"]を使用して子要素にアクセスできます。これらはチェーン化できます:xmlDoc ["Root"] ["Folder"] ["Item"]階層(これらの要素が実際に存在することを検証することは賢明です)
Jason Williams

1
InnerTextここでは、そのノードの値を取得し、子ノードのすべての値と連結します-そうですか?奇妙なことをしたいようです。
Don Cheadle

17
女友達のリストを持つプログラマー?シェニガン!
E.ヴァンプッテン2017

1
@ E.vanPuttenはこの日と年齢ではありません。これはオタクの復讐ではありません
user405205​​4

@DonCheadle 子ノードが存在することを期待していない場合はInnerText、ノード値を返すだけです。これは、私(およびおそらくこの質問を読んでいる人)がXMLを解析して最初に見つけるものです。
-F1Krazy

48

適切なXSDスキーマを使用してxsd.exeでクラスのセットを作成し、を使用しXmlSerializerてXMLからオブジェクトツリーを作成します。逆も同様です。モデルにほとんど制限がない場合は、モデルクラスとXml * Attributesを使用してXMLの間に直接マッピングを作成することもできます。

MSDNには、XMLシリアル化に関する紹介記事があります

パフォーマンスのヒント:の作成にXmlSerializerはコストがかかります。XmlSerializer複数のXMLファイルを解析または書き込む場合は、インスタンスへの参照を保持してください。



5
良い例は、マイクロソフトからのこの例の真ん中にある「購入注文の例」です。msdn.microsoft.com/en-us/library/58a18dwa.aspx。スキーマを作成する必要がなくなります。c#クラスはC#属性で装飾されたスキーマです。
マークラカタ2013

25

大量のデータ(数メガバイト)を処理している場合はXmlReader、XMLのストリーム解析に使用する必要があります。

(それ以外はXPathNavigatorXElementXmlDocumentでも、とXmlSerializerあなたは完全な生成されたオブジェクトグラフを置いている場合)になります高いメモリ使用量も非常に遅いロード時間をと。

もちろん、とにかくメモリ内のすべてのデータが必要な場合は、あまり選択肢がないかもしれません。


18

使用XmlTextReaderXmlReaderXmlNodeReaderおよびSystem.Xml.XPath名前空間。そして、( 、XPathNavigatorXPathDocument、)。XPathExpressionXPathnodeIterator

通常XPath、XMLが読みやすくなります。


2
参考までに、new XmlTextReader()またはを使用しないでくださいnew XmlTextWriter()。.NET 2.0以降は非推奨です。XmlReader.Create()またはXmlWriter.Create()代わりに使用します。
John Saunders

10

私は最近、XMLドキュメントの解析を伴うアプリケーションでの作業を要求されたばかりであり、LINQ to XMLベースのアプローチが私の意見では最良であるというJon Gallowayに同意します。しかし、私は使用可能な例を見つけるために少し掘る必要があったので、さらに面倒なことなく、ここにいくつかあります!

このコードは機能するため、コメントは歓迎しますが、完全ではない可能性があります。このプロジェクトの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、そのサブクラスXmlTextReader、およびを試してくださいXmlValidatingReader。これらは、XMLファイルを解析するための高速で軽量な(メモリ使用量など)、前方専用の方法を提供します。

XPath機能が必要な場合は、を試してくださいXPathNavigator。ドキュメント全体をメモリに保存する必要がある場合は、を試してくださいXmlDocument


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解析のベストプラクティス」が存在するかどうかはわかりません。さまざまな状況に適したテクノロジーは数多くあります。どちらの方法を使用するかは、具体的なシナリオによって異なります。

あなたが行くことができるXMLにLINQXmlReaderXPathNavigatorあるいは正規表現。あなたがあなたのニーズを詳しく述べているならば、私はいくつかの提案をするように試みることができます。


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

.NETの標準XMLシリアライザーは非常に制限されています。

  • 循環参照を持つクラスまたはインターフェイスプロパティを持つクラスのシリアル化をサポートしていません。
  • 辞書をサポートしていません、
  • 古いバージョンのXMLを読み取るメカニズムはありません。
  • カスタムシリアライザーを作成する場合、クラスはIXmlSerializableから継承する必要があります。つまり、あなたのクラスはPOCOクラスではありません。
  • IoCをサポートしません。

ExtendedXmlSerializerは、これ以上のことを実行できます。

ExtendedXmlSerializerは、.NET 4.5以降および.NET Coreをサポートしています。WebApiおよびAspCoreと統合できます。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.