Como se pode encontrar namespaces XML desconhecidos em um documento?
-
21-08-2019 - |
Pergunta
Especificamente (respirando fundo.): Como você vai encontrar todos os espaços de nomes XML dentro de um C # / NET XmlDocument
para o qual não existem esquemas aplicáveis ??em XmlSchemaSet
da instância (propriedade Schemas
)
Minha magia XPath está faltando a sofisticação de fazer algo assim, mas eu vou continuar procurando, entretanto ...
Solução
Você precisa obter uma lista de todos os espaços de nomes distintos no documento e, em seguida, comparar com os espaços de nomes distintas no conjunto de esquema.
Mas os nomes de declaração namespace normalmente não estão expostos no modelo de documento XPath. Mas dado um nó você pode obter o seu namespace:
// 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);
Outras dicas
A maneira mais fácil que eu já encontrei para recuperar todos os namespaces de um determinado XmlDocument é XPath através de todos os nós encontrando valores exclusivos prefixo e NamespaceURI.
Eu tenho uma rotina auxiliar que eu uso para retornar esses valores exclusivos em um XmlNamespaceManager para tornar a vida mais simples quando eu estou lidando com documentos XML complexos.
O código é a seguinte:
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;
}