2010-03-24 17 views
10

Tengo un documento Xml que define y hace referencia a algunos espacios de nombres. Lo cargo en un objeto XmlDocument y, a mi leal saber y entender, creo un objeto XmlNamespaceManager con el que consultar Xpath. El problema es que recibo excepciones de XPath de que el espacio de nombres "mi" no está definido. ¿Cómo hago que el administrador del espacio de nombres vea que los espacios de nombres a los que me refiero ya están definidos? O más bien, ¿cómo obtengo las definiciones del espacio de nombres del documento en el administrador del espacio de nombres?Consultar un XmlDocument sin obtener un problema de 'No se define el prefijo del espacio de nombres'

Además, me parece extraño que en primer lugar tenga que proporcionar un administrador de espacio de nombres al documento que crea a partir de la tabla de nombres de los documentos. Incluso si necesita codificar espacios de nombres manuales, ¿por qué no puede agregarlos directamente al documento? ¿Por qué siempre tiene que pasar este administrador de espacio de nombres con cada consulta? ¿Qué no puede XmlDocument solo saber?

Código:

XmlDocument xmlDoc = new XmlDocument(); 
xmlDoc.Load(programFiles + @"Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\HfscBookingWorkflow\template.xml"); 
XmlNamespaceManager ns = new XmlNamespaceManager(xmlDoc.NameTable); 

XmlNode referenceNode = xmlDoc.SelectSingleNode("/my:myFields/my:ReferenceNumber", ns); 
referenceNode.InnerXml = this.bookingData.ReferenceNumber; 

XmlNode titleNode = xmlDoc.SelectSingleNode("/my:myFields/my:Title", ns); 
titleNode.InnerXml = this.bookingData.FamilyName; 

xml:

<?xml version="1.0" encoding="UTF-8" ?> 
    <?mso-infoPathSolution name="urn:schemas-microsoft-com:office:infopath:Inspection:-myXSD-2010-01-15T18-21-55" solutionVersion="1.0.0.104" productVersion="12.0.0" PIVersion="1.0.0.0" ?> 
    <?mso-application progid="InfoPath.Document" versionProgid="InfoPath.Document.2"?> 
    <my:myFields xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:my="http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55" xmlns:xd="http://schemas.microsoft.com/office/infopath/2003"> 
    <my:DateRequested xsi:nil="true" /> 
    <my:DateVisited xsi:nil="true" /> 
    <my:ReferenceNumber /> 
    <my:FireCall>false</my:FireCall> 

Actualización:

ns.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 
ns.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml"); 
ns.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003"); 
ns.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55"); 

Esto hace el trabajo, sino que quiere decir es que he de código sea difícil de este XML particular, esquema. Este esquema representa una plantilla de formulario de infopath. En particular, la URL de mi espacio de nombres será diferente para cada plantilla de formulario, así que realmente no quiero codificarla. Sería bueno encontrar una forma limpia de obtener este espacio de nombres del xml sin recurrir a RegEx.

Tenía la esperanza de que XmlNamespaceManager seleccionara las definiciones de espacio de nombres de NameTable. Me refiero a su en el Xml, pero aún tengo que definirlos.

Respuesta

5
ns.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 
ns.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml"); 
ns.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003"); 
ns.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55"); 

Esto hace el trabajo, sino que quiere decir es que he a codificar a este esquema XML en particular. Este esquema representa una plantilla de formulario de infopath. En particular, la URL de mi espacio de nombres será diferente para cada plantilla de formulario, así que realmente no quiero codificarla. Sería bueno encontrar una manera limpia de obtener este espacio de nombres del xml sin recurrir a Regex.

Tenía la esperanza de que XmlNamespaceManager seleccionara las definiciones de espacio de nombres de NameTable. Me refiero a su en el Xml, pero aún tengo que definirlos.

1

¿Ha definido "mi" en el gestor de espacio de nombres?

ns.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-01-15T18:21:55"); 

O mejor: elija algo que no sea probable que entre en conflicto. Sin embargo, parece extraño que no lo haya recogido de la tabla de nombres.

+1

NameTable es sólo una optimización para almacenar nombres. Realmente no tiene nada que ver con los espacios de nombres. E incluso si XmlNamespaceManager pudiera inferir todos los espacios de nombres y prefijos del documento XML que no ayudaría en el caso general debido a la naturaleza de los espacios de nombres XML, p. lo que habría mapa XmlNamespaceManager "mi" prefijo en este caso:

+0

@Oleg - Creo debería haber conservado su respuesta (en lugar de eliminarla): es una buena respuesta al "¿por qué?". –

+0

No lo he agregado manualmente porque es probable que la url del espacio de nombres cambie. Los campos a los que trato de llegar con XPath no lo harán. –

3

Aquí está la respuesta al "¿Qué no puede XmlDocument solo saber?" pregunta.

NameTable es solo una optimización para almacenar nombres. Realmente no tiene nada que ver con los espacios de nombres.

E incluso si XmlNamespaceManager pudiera inferir todos los espacios de nombres y prefijos del documento XML que no ayuda en el caso general debido a la naturaleza de espacios de nombres XML, p. lo que XmlNamespaceManager mapa "mi" prefijo en este caso:

<root> 
    <foo xmlns:my="blah"/> 
    <foo xmlns:my="balh-blah-blah"/> 
</root> 
0

para mí con InfoPath 2007 esta resuelto el problema

static public XmlNamespaceManager GetNameSpaceManager(this XmlDocument document) 
{ 
    XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(document.NameTable); 

    xmlNamespaceManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 
    xmlNamespaceManager.AddNamespace("dfs", "http://schemas.microsoft.com/office/infopath/2003/dataFormSolution"); 
    xmlNamespaceManager.AddNamespace("d", "http://schemas.microsoft.com/office/infopath/2003/ado/dataFields"); 
    xmlNamespaceManager.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2012-03-29T06:28:28"); 
    xmlNamespaceManager.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003"); 

    return xmlNamespaceManager; 
} 
Cuestiones relacionadas