Problemas com a utilização de XPath na .NET Framework

Este é um artigo um pouco diferente do que normalmente coloco no blog!

Recentemente tive de recorrer à utilização de XPath numa aplicação em .NET 4.0, e deparei-me com alguns problemas inesperados!

Suponhamos que temos um ficheiro chamado “teste.xml” com o seguinte conteúdo:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
  <PropertyGroup>
    <ProductVersion>9.0.30729</ProductVersion>
  </PropertyGroup>
</Project>

Agora, com base neste ficheiro, executam o seguinte código em .NET:

var doc = new XmlDocument(); //Criar XmlDocument

doc.Load("teste.xml"); //Carregar o ficheiro teste.xml

var node = doc.SelectSingleNode("/Project"); //Obter o nó raiz com uma expressão de XPath

Ora pela lógica, neste momento a variável “node” deveria ter o nó raiz do nosso XML, certo?

ERRADO!!!

Acontece que pelo menos até à actual .NET Framework 4.0, as base classes apenas contemplam XPath 1.0, em que a noção de “default namespace” (indicado no XML com o atributo “xmlns”) não existe, sendo assim obrigatória a sua indicação!

Para ultrapassar este problema, sugiro algumas soluções:

Solução 1: passar o default namespace a ser apenas mais um namespace declarado (isto sim, compatível com XPath 1.0)

var doc = new XmlDocument();  //Criar XmlDocument

doc.Load("teste.xml"); //Carregar o ficheiro teste.xml

var nsm = new XmlNamespaceManager(doc.NameTable);

nsm.AddNamespace("xxx", doc.DocumentElement.NamespaceURI);

var node = doc.SelectSingleNode("/xxx:Project", nsm); //Obter o nó raiz com uma expressão de XPath

Solução 2: remover o “default namespace” (carinhosamente chamada de “solução-martelo”)

var doc = new XmlDocument();  //Criar XmlDocument

doc.Load("teste.xml"); //Carregar o ficheiro teste.xml

if (doc.DocumentElement.HasAttribute("xmlns"))
{
    doc.DocumentElement.SetAttribute("xmlns", string.Empty);
    doc.Load(doc.OuterXml);
}

var node = doc.SelectSingleNode("/Project"); //Obter o nó raiz com uma expressão de XPath

Solução 3: utilizar bibliotecas de terceiros em vez do normal System.Xml, quem implementam as mais recentes tecnologias como XPath 2.0

Apesar de eu ter utilizado XmlDocument, este é um comportamento que afecta também o “LINQ to XML” (XDocument e afins… :-P ) quando pretendem aplicar XPath a estes!

Bom XPath’ing a todos!

Posts Relacionados:

  1. SharpDevelop e a .NET Compact Framework
  2. Disponibilizado Código-Fonte da .NET Framework
  3. Visual Studio 2010 e .NET Framework 4.0
  4. MCP Update: “TS: .NET Framework 4, Windows Applications”

One thought on “Problemas com a utilização de XPath na .NET Framework

Deixar uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *

*

Pode usar estas etiquetas HTML e atributos: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>