3

ルート要素のノードを取得するコードがあります。

xmlNodes = rootElement.SelectNodes("DefinitionName");

存在するノードを返しません。デバッガーで、rootElement を展開して DefinitionName を見つけることができます。どうやら問題は、ファイルに名前空間が定義されていることです (以下の XML を参照)。MSDNは、ノードを返すには次のようなことをしなければならないと言っています。

注: これは私のコードとは関係ありません。これは MSDN の例です。

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("ab", "http://www.lucernepublishing.com");
XmlNodeList nodelist = doc.SelectNodes("//ab:book", nsmgr);

2 つの質問があります。

  1. 名前空間が重要なのはなぜですか? ノードが必要で、それが存在する場合は、それを私に渡してください。
  2. 私のアプリは多くの XML ファイルを処理します。名前空間 ( ) を指定するにはどうすればよいですnsmgr.AddNamespace()か? 最初にファイルを取得するためにファイルを解析する必要がありますか?

不安に満ちた長い道のりを歩んでいると感じずにはいられません。

これは XML です。

    <?xml version="1.0" encoding="utf-8"?>
    <SessionStateInfo xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
    z:Id="1" z:Type="Company.Apps.MoreHere.Session.SessionStateInfo"
    z:Assembly="assembly info here"
    xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/"
    xmlns="http://schemas.datacontract.org/2004/07/MoreHere.Session">
      <CoaterNumber>25</CoaterNumber>
      <DefinitionName z:Id="2">Two Line</DefinitionName>
      <EnableManualMode>true</EnableManualMode>
4

3 に答える 3

4
<SessionStateInfo ....
    xmlns="http://schemas.datacontract.org/2004/07/MoreHere.Session">

この要素とそのすべての子孫がhttp://schemas.datacontract.org/2004/07/MoreHere.Session名前空間にあることを意味します。XPath 内のプレフィックスのない名前は、常に名前空間のない要素を参照するため、この URI をプレフィックスにバインドし、ドキュメント内でプレフィックスが使用されていなくても、XPath でそのプレフィックスを使用する必要があります。

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("mhs", "http://schemas.datacontract.org/2004/07/MoreHere.Session");
xmlNodes = rootElement.SelectNodes("mhs:DefinitionName", nsmgr);

探している要素が常に同じローカル名を持つが、名前空間がある場合とない場合 (または名前空間が異なる場合) がわかっている場合は、次のような XPath トリックを使用できます。

rootElement.SelectNodes("*[local-name() = 'DefinitionName']");
于 2013-03-28T16:11:02.947 に答える
2

名前空間がアタッチされている場合、「DefinitionName」では不十分であるため、これは重要です。John というファーストネームを持つ人々のリストが与えられたと想像してください。

  • ジョンスミス
  • ジョン・ジョーンズ
  • ジョン・マーフィー

あなたがしていることは、たとえば「John Smith」ではなく「John」と尋ねることと同じです。

于 2013-03-28T16:13:03.373 に答える
1

これは質問に対する正確な答えではありませんが、次を使用した代替ソリューションである可能性がありますXDocument

using System;
using System.Dynamic;
using System.Xml.Linq;
using Microsoft.CSharp.RuntimeBinder;
using System.Linq;

namespace ConsoleApplication8
{
    class Program
    {
        static void Main(string[] args)
        {
            XDocument document = XDocument.Load("SessionStateInfo.xml");
            XNamespace nameSpace = document.Root.GetDefaultNamespace();
            XElement node = document.Descendants(nameSpace + "DefinitionName").FirstOrDefault();   

            if (node != null)
            {
                Console.WriteLine("Cool! XDocument rocks! value: {0}", node.Value);
            }
            else
            {
                Console.WriteLine("Spoot! Didn't find it!");
            }
        }      
    }       
}

これは、デフォルトの名前空間が指定されているかどうかに関係なく機能するようです。

于 2013-03-28T20:35:41.223 に答える