2009-04-20 7 views
10

私の基本的な要件は、XMLファイルから要素の値を取得することです、私はXMLDoxument.SelectSingleNodeを使用しています。私のXMLファイルにはヘッダーに名前空間がいくつか含まれているので、NameSpaceManagerを使用してnamespace-prefixを追加し、その特定の要素を取得するために接頭辞を使用しています。今私のXMLファイルでは、名前空間が変化しています。私はハードコーディングをしたくありません。すべての名前空間を見つけることができ、NameSpaceManagerに追加することができます。XMLのすべてのネームスペースをどのようにリストすることができますか?

ありがとうございました。

+0

@Ruchita:このアプローチの問題点は、名前空間の宣言を上書きすることができることです(XML 1.0では、デフォルトの名前空間宣言もXML 1でリセットできます)。1すべての名前空間宣言) –

答えて

2

XmlDocumentから名前空間を取得する基本的な問題は、XmlDocumentのNameTableを取得し、を作成するだけで解決できます。

しかし、他の目的で名前空間をリストしたい場合は、XmlNamespaceManagerクラスとXPathNavigatorクラスで公開されているGetNamespacesInScopeメソッドをチェックアウトする必要があります。 XmlDocumentオブジェクトを使用する場合は

、次のコードを経由して、それからてXmlNamespaceManagerを取得することができます。

//Instantiate an XmlDocument object. 
XmlDocument xmldoc = new XmlDocument(); 

//Load XML file into the XmlDocument object. 
xmldoc.Load("C:\\myFile.xml"); 

//Instantiate an XmlNamespaceManager object. 
XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmldoc.NameTable); 

// Retrieve the namespaces into a Generic dictionary with string keys. 
IDictionary<string, string> dic = nsMgr.GetNamespacesInScope(XmlNamespaceScope.All); 

// Iterate through the dictionary. 

... 

In this article、スコットHanselman氏はのXPathNavigatorを使用して、ドキュメント内のすべての名前空間を一覧表示するには、このメソッドを使用する方法を提示し、 LINQブリッジを使用します。あなたの迅速な対応のための

+2

これは私にとってはうまくいかないようです。ドキュメントのNameTableには多くの項目がありますが、ドキュメントの冒頭に定義されているいくつかの名前空間はXmlNamespaceManagerに追加されていません。名前空間を手動でマネージャに追加しない限り、SelectNodes呼び出しで「名前空間が定義されていません」という状態が続きます。 XML文書で定義されている名前空間を正確に読み取って名前空間マネージャーに追加するソリューションが必要なので、それらをハードコードする必要はありません。 –

+0

@SeanWorle少し遅れますが、[XPathDocumentとLINQをXMLドキュメントからXMLへネームスペースを取得](http://www.hanselman.com/blog/CommentView.aspx?guid=51861b63-526f-4572- ba84-2f24a1c7bd83)、おそらくあなたや他の人を助けるかもしれません。 – ErikE

+1

このアプローチの問題は、 "xmlns"エントリを無視することです。 –

7

おかげで...

私は、あなたが最新のものでなければなりません使用している.NETバージョンだと思います。私は...かなり古いの.NET Framework 1.1を使用しています:(..

を時点で,,私はこのようないくつかのサンプルコードを持っている...同じ目的のために...

XmlNodeList _xmlNameSpaceList = _xmlDocument.SelectNodes(@"//namespace::*[not(. = ../../namespace::*)]"); 

      _xmlNSmgr = new XmlNamespaceManager(_xmlDocument.NameTable);   

      foreach(XmlNode nsNode in _xmlNameSpaceList) 
      { 
       _xmlNSmgr.AddNamespace(nsNode.LocalName,nsNode.Value); 
      } 

どれをコメントは私のKBに知識を追加することを歓迎します... ありがとう

+0

古いXPathは完全にうまく動作し、名前空間を持つすべてのノードを取得します。ありがとう – zulucoda

-2

XmlDocumentを行う前に、ネームスペースの問題を避けるために簡単な方法を探しているなら、 .LoadXml(bla)。ライブXHTMLページを解析するときにこれを行います。XmlDocの読み込み時間を15秒から.15秒にして、xpathsにプレフィックスを付ける必要がないようにします。 。

13

名前空間はXML文書内のどこにでもあります。だから、すべての名前空間を抽出し、私は次のようでしたてXmlNamespaceManagerにそれらを宣言します

public static XmlNamespaceManager getAllNamespaces(XmlDocument xDoc) 
{ 
    XmlNamespaceManager result = new XmlNamespaceManager(xDoc.NameTable); 

    IDictionary<string, string> localNamespaces = null; 
    XPathNavigator xNav = xDoc.CreateNavigator(); 
    while (xNav.MoveToFollowing(XPathNodeType.Element)) 
    { 
     localNamespaces = xNav.GetNamespacesInScope(XmlNamespaceScope.Local); 
     foreach (var localNamespace in localNamespaces) 
     { 
      string prefix = localNamespace.Key; 
      if (string.IsNullOrEmpty(prefix)) 
        prefix = "DEFAULT"; 

      result.AddNamespace(prefix, localNamespace.Value); 
     } 
    } 

    return result; 
} 

ただ、デフォルトの名前空間の場合に注意を払います。既定の名前空間を照会するときに上記の返された名前空間マネージャーを使用してSelectSingleNodeを作成する際に問題があったため、既定の名前空間を "DEFAULT"プレフィックスとして再定義しました。私は私の回避策でした。 欲しいものは

0

XmlDocumentの作業用ソリューションを投稿しました。しかし、私はXDocumentと同じことをしたかった。ここでXDocumentと全く同じである:

var xml = XDocument.Load(filename); 
var xmlNameSpaceList = ((IEnumerable)xml.XPathEvaluate(@"//namespace::*[not(. = ../../namespace::*)]")).Cast<XAttribute>(); 
var xmlNSmgr = new XmlNamespaceManager(new NameTable()); 
foreach (var nsNode in xmlNameSpaceList) 
{ 
    xmlNSmgr.AddNamespace(nsNode.Name.LocalName, nsNode.Value); 
} 

今、あなたは、例えば、名前空間とXPathを使用することができますxml.XPathEvaluate("//test:p", xmlNSmgr)

関連する問題