Как найти неизвестные пространства имен XML в документе? - PullRequest
1 голос
/ 04 февраля 2009

В частности (глубоко вздохнув): как бы вы нашли все пространства имен XML в C # /. NET XmlDocument, для которых нет подходящих схем в свойстве XmlSchemaSet (Schemas) экземпляра?

Моей магии XPath не хватает изощренности, чтобы делать что-то подобное, но я буду продолжать искать ...

Ответы [ 2 ]

3 голосов
/ 27 января 2011

Самый простой способ, который я когда-либо нашел для получения всех пространств имен из данного XmlDocument, - это XPath через все узлы, находящие уникальные значения Prefix и NamespaceURI.

У меня есть вспомогательная процедура, которую я использую для возврата этих уникальных значений в XmlNamespaceManager, чтобы упростить жизнь, когда я имею дело со сложными документами Xml.

Код выглядит следующим образом:

private static XmlNamespaceManager PrepopulateNamespaces( XmlDocument document )
{
    XmlNamespaceManager result = new XmlNamespaceManager( document.NameTable );
    var namespaces = ( from XmlNode n in document.SelectNodes( "//*|@*" )
                       where n.NamespaceURI != string.Empty
                       select new
                       {
                           Prefix = n.Prefix,
                           Namespace = n.NamespaceURI
                       } ).Distinct();

    foreach ( var item in namespaces )
        result.AddNamespace( item.Prefix, item.Namespace );

    return result;
}
1 голос
/ 01 августа 2009

Необходимо получить список всех отдельных пространств имен в документе, а затем сравнить его с различными пространствами имен в наборе схем.

Но имена объявлений пространства имен обычно не отображаются в модели документа XPath. Но с учетом узла вы можете получить его пространство имен:

// Match every element and attribute in the document
var allNodes = xmlDoc.SelectNodes("//(*|@*)");
var found = new Dictionary<String, bool>(); // Want a Set<string> really
foreach (XmlNode n in allNodes) {
  found[n.NamespaceURI] = true;
}
var allNamespaces = found.Keys.OrderBy(s => s);
...