web-dev-qa-db-ja.com

XDocumentからNameTableを取得するにはどうすればよいですか?

XDocumentからNameTableを取得するにはどうすればよいですか?

XmlDocumentが持っているNameTableプロパティを持っていないようです。

編集:答えの欠如から判断すると、私は要点を見逃しているかもしれないと推測しています。

私はこのようなXDocumentに対してXPathクエリを実行しています...

document.XPathSelectElements("//xx:Name", namespaceManager);

正常に動作しますが、XmlDocumentの場合のようにXDocumentから既存の名前空間を取得するのではなく、使用する名前空間をXmlNamespaceManagerに手動で追加する必要があります。

42
Simon Keep

XmlReaderを介してXMLをプッシュし、XmlReaderのNameTableプロパティを使用する必要があります。

XDocumentにロードするXmlが既にある場合は、必ずXmlReaderを使用してXDocumentをロードしてください。-

XmlReader reader = new XmlTextReader(someStream);
XDocument doc = XDocument.Load(reader);
XmlNameTable table = reader.NameTable;

XDocumentを使用してXmlを最初から作成する場合は、XDocumentのCreateReaderメソッドを呼び出してから、何かがリーダーを消費するようにする必要があります。リーダーが使用されたら(たとえば、別のXDocumentをロードしますが、リーダーにXDocumentのコンテンツを実行させるだけのシンクを行わない方がよいでしょう)、NameTableを取得できます。

31
AnthonyWJones

私はこのようにしました:

//Get the data into the XDoc
XDocument doc = XDocument.Parse(data);
//Grab the reader
var reader = doc.CreateReader();
//Set the root
var root = doc.Root;
//Use the reader NameTable
var namespaceManager = new XmlNamespaceManager(reader.NameTable);
//Add the GeoRSS NS
namespaceManager.AddNamespace("georss", "http://www.georss.org/georss");  
//Do something with it
Debug.WriteLine(root.XPathSelectElement("//georss:point", namespaceManager).Value);  

マット

24

XmlDocumentの場合のように、XDocumentから既存の名前空間を取得するのではなく、使用する名前空間をXmlNamespaceManagerに手動で追加する必要があります。

XDocument project = XDocument.Load(path);
//Or: XDocument project = XDocument.Parse(xml);
var nsMgr = new XmlNamespaceManager(new NameTable());
//Or: var nsMgr = new XmlNamespaceManager(doc.CreateReader().NameTable);
nsMgr.AddNamespace("msproj", "http://schemas.Microsoft.com/developer/msbuild/2003");
var itemGroups = project.XPathSelectElements(@"msproj:Project/msproj:ItemGroup", nsMgr).ToList();
6
Alex

XPathNavigatorでも実行できます。 Xmlファイルエンコーディングも名前空間プレフィックスも知らない場合に役立ちます。

XDocument xdoc = XDocument.Load(sourceFileName);
XPathNavigator navi = xdoc.Root.CreateNavigator();
XmlNamespaceManager xmlNSM = new XmlNamespaceManager(navi.NameTable);
//Get all the namespaces from navigator
IDictionary<string, string> dict = navi.GetNamespacesInScope(XmlNamespaceScope.All);
//Copy them into Manager
foreach (KeyValuePair<string, string> pair in dict)
{
    xmlNSM.AddNamespace(pair.Key, pair.Value);
}