Compartir a través de


Trabajar con las clases XPathNavigator y XPathNodeIterator

Para obtener acceso a los datos XML y manipularlos en los orígenes de datos de la plantilla de formulario, muchos miembros del modelo de objetos de código administrado proporcionado por el espacio de nombres Microsoft.Office.InfoPath crean (o se les pasa) una instancia de la clase XPathNavigator del espacio de nombres System.Xml.XPath. Una vez que se tiene acceso a un objeto XPathNavigator devuelto por un miembro del modelo de objetos de InfoPath, se pueden usar las propiedades y los métodos de la clase XPathNavigator para trabajar con los datos.

El miembro usado con más frecuencia del espacio de nombres Microsoft.Office.InfoPath que usa la clase XPathNavigator es el método CreateNavigator de la clase DataSource , que permite trabajar con los datos almacenados, representados por un objeto DataSource. El método CreateNavigator crea un objeto XPathNavigator colocado en la raíz del origen de datos representado por el objeto DataSource.

Sugerencia

[!SUGERENCIA] Si está familiarizado con el uso de MSXML5 para trabajar con datos en Microsoft InfoPath 2003, puede considerar el método CreateNavigator como un reemplazo de la propiedad DOM de DataObject.

Uso de la clase XPathNavigator para obtener acceso al origen de datos principal del formulario

Para obtener acceso al origen de datos principal del formulario, llame al método CreateNavigator directamente desde la palabra clave this (C#) o Me (Visual Basic). En el ejemplo siguiente se usa el método CreateNavigator para crear un objeto XPathNavigator colocado en la raíz del origen de datos principal y, a continuación, se usa la propiedad OuterXml de la clase XPathNavigator para mostrar el XML devuelto en un cuadro de mensaje.

XPathNavigator myNavigator = 
   this.CreateNavigator();
MessageBox.Show("Main data source XML: " +
   myNavigator.OuterXml.ToString());
Dim myNavigator As XPathNavigator  = _
   Me.CreateNavigator()
MessageBox.Show("Main data source XML: " & _
   myNavigator.OuterXml.ToString())

Nota:

Llamar al método CreateNavigator directamente desde la palabra clave this o Me equivale a llamar al método CreateNavigator mediante la propiedad MainDataSource ( this.MainDataSource.CreateNavigator()) o pasando una cadena vacía a la propiedad DataSources de la clase XmlForm ( this.DataSources[""].CreateNavigator()).

Selección y configuración de los nodos XML para campos en el origen de datos principal

Para seleccionar el nodo XML único para un campo en un origen de datos, use el método SelectSingleNode(String,IXmlNamespaceResolver) de la clase XPathNavigator. Si desea trabajar con un conjunto de campos o grupos de repetición, use el método Select(String,IXmlNamespaceResolver) de la clase XPathNavigator. Este método devuelve un objeto XPathNodeIterator que representa una colección de nodos.

Selección y configuración del valor de un único nodo

El método SelectSingleNode sobrecargado que debe usar tiene un parámetro xpath que toma una expresión XPath como una cadena y un parámetro de resolución que toma un objeto XmlNamespaceManager para resolver prefijos de espacio de nombres. Para seleccionar un único nodo en el origen de datos principal del formulario, pase una expresión XPath que especifique el campo o grupo que desea seleccionar para el parámetro xpath , junto con el objeto XmlNamespaceManager devuelto por la propiedad NamespaceManager del objeto XmlForm . El objeto XmlNamespaceManager devuelto se inicializa en el momento de carga con todos los espacios de nombres definidos por el archivo de definición de formulario (.xsf) de la plantilla de formulario.

Sugerencia

[!SUGERENCIA] La manera más sencilla de crear una expresión XPath para seleccionar un nodo en el origen de datos del formulario consiste en hacer clic con el botón secundario en el campo o grupo del panel de tareas Campos y elegir Copiar XPath. Para crear y probar expresiones XPath editadas manualmente para obtener acceso a los nodos de un esquema XML complejo o muy anidado, agregue un control Cuadro de expresión al formulario, especifique la expresión XPath para el control y obtenga una vista previa del formulario para mostrar los resultados.

En el ejemplo siguiente se usa el método SelectSingleNode para seleccionar el nodo único para el EmailAlias campo. A continuación, se usa el método SetValue de la clase XPathNavigator y la propiedad UserName de la clase User para establecer el valor del campo en el alias del usuario actual.

XPathNavigator emailAlias = 
   this.CreateNavigator().SelectSingleNode(
      "/my:myFields/my:EmailAlias", NamespaceManager);
emailAlias.SetValue(this.Application.User.UserName.ToString());
Dim emailAlias As XPathNavigator = _
   Me.CreateNavigator().SelectSingleNode( _
      "/my:myFields/my:EmailAlias", NamespaceManager)
emailAlias.SetValue(Me.Application.User.UserName.ToString())

Para obtener información acerca del procedimiento para crear expresiones XPath, vea el tema sobre referencia de XPath en MSDN y el artículo de recomendación de W3C del Lenguaje de rutas XML (XPath), versión 1.0.

Configuración del valor de un nodo que tiene el atributo xsi:nil

Para determinados tipos de datos, al intentar establecer el valor de un campo en blanco mediante programación, se produce el error "Error de validación de esquema encontrados errores de tipo que no son de datos". Normalmente, la causa de este error es que el elemento tiene el atributo xsi:nil establecido en true. Si se examina el elemento XML subyacente para el campo en blanco del formulario, se puede ver este valor de configuración. Por ejemplo, el fragmento XML para el siguiente campo Fecha en blanco tiene el atributo xsi:nil establecido en true.

<my:myDate xsi:nil="true"></my:myDate>

Si el atributo xsi:nil está establecido en true, significa que el elemento está presente pero no tiene ningún valor, es decir, es nulo. Si intenta establecer mediante programación el valor de dicho nodo, InfoPath mostrará el mensaje "La validación del esquema encontró errores que no son de tipo de datos" porque el elemento está marcado actualmente como nulo. InfoPath establece el atributo xsi:nil en true para los campos nulo de los siguientes tipos de datos:

  • Whole Number (integer)

  • Decimal (double)

  • Date (date)

  • Time (time)

  • Date and Time (dateTime)

Para evitar este error, debe probarse el código para el atributo xsi:nil y, si está presente, quitarlo antes de configurar el valor del nodo. La siguiente subrutina toma un objeto XpathNavigator colocado en el nodo que desea configurar, busca el atributo nil y, si lo encuentra, lo elimina.

public void DeleteNil(XPathNavigator node)
{
   if (node.MoveToAttribute(
      "nil", "https://www.w3.org/2001/XMLSchema-instance"))
      node.DeleteSelf();
}
Public Sub DeleteNil(ByVal node As XPathNavigator)
   If (node.MoveToAttribute( _
      "nil", "https://www.w3.org/2001/XMLSchema-instance")) Then
      node.DeleteSelf()
   End If
End Sub

Se puede llamar a esta subrutina antes de intentar configurar un campo de un tipo de datos que podría tener el atributo xsi:nil, como se muestra en el siguiente ejemplo que configura un campo Fecha.

// Access the main data source.
XPathNavigator myForm = this.CreateNavigator();
// Select the field.
XPathNavigator myDate = myForm.SelectSingleNode("/my:myFields/my:myDate", NamespaceManager);
// Check for and remove the "nil" attribute.
DeleteNil(myDate);
// Build the current date in the proper format. (yyyy-mm-dd)
string curDate = DateTime.Today.Year + "-" + DateTime.Today.Month + 
   "-" + DateTime.Today.Day;
// Set the value of the myDate field.
myDate.SetValue(strCurDate);
' Access the main data source.
Dim myForm As XPathNavigator = Me.CreateNavigator()
' Select the field.
Dim myDate As XPathNavigator = _
   myForm.SelectSingleNode("/my:myFields/my:myDate", NamespaceManager)
' Check for and remove the "nil" attribute.
DeleteNil(myDate)
' Build the current date in the proper format. (yyyy-mm-dd)
Dim curDate As String = DateTime.Today.Year + "-" + _
   DateTime.Today.Month + "-" + DateTime.Today.Day
' Set the value of the myDate field.
myDate.SetValue(strCurDate)

Nota:

[!NOTA] Aunque la implementación del objeto XPathNavigator en InfoPath expone el método SetTypedValue (que se usa para configurar un nodo mediante un valor de un tipo específico), InfoPath no implementa dicho método. En su lugar, debe usar el método SetValue y pasar un valor de cadena del formato correcto para el tipo de datos del nodo.

Selección y configuración de un conjunto de nodos de repetición

Para especificar un conjunto de campos o grupos de repetición que sean de un número indeterminado, use el método Select de la clase XPathNavigator. Este método devuelve un objeto XPathNodeIterator que puede usarse para procesar una iteración en la colección de nodos especificada.

En el ejemplo siguiente se supone que la plantilla de formulario contiene una lista con viñetas o un control repetido similar que está enlazado a un elemento repetido denominado field1. El XPath del campo se pasa al método Select y el XPathNodeIterator devuelto se asigna a la nodes variable . A continuación, se usa el método MoveNext para procesar una iteración en la colección de nodos, y la propiedad Current para devolver un objeto XPathNavigator colocado en el nodo actual. Por último, use la propiedad Value para recuperar y mostrar el valor de cada campo repetido.

string message = String.Empty;
XPathNavigator root = this.CreateNavigator();
XPathNodeIterator nodes = 
   root.Select("/my:myFields/my:group1/my:field1", NamespaceManager);
while (nodes.MoveNext())
{
    message += nodes.Current.Value + System.Environment.NewLine;
}
MessageBox.Show(message);
Dim message As String = String.Empty
Dim root As XPathNavigator = Me.CreateNavigator()
Dim nodes As XPathNodeIterator = _
   root.Select("/my:myFields/my:group1/my:field1", NamespaceManager)
Do While nodes.MoveNext
    message += nodes.Current.Value &amp; System.Environment.NewLine
Loop
MessageBox.Show(message)

En el ejemplo anterior se trabaja con valores de cadena en el campo de repetición especificado. Sin embargo, si el campo contiene valores numéricos, se puede usar un código similar para procesar una iteración en los valores del campo para que realicen operaciones aritméticas, como calcular el total o el promedio de los valores.

Del mismo modo, en lugar de usar la propiedad Value para recuperar el valor de cada instancia del campo de repetición, puede usar el método SetValue para procesar una iteración en los campos y configurar sus valores, como se muestra en el ejemplo siguiente.

XPathNavigator root = this.CreateNavigator();
XPathNodeIterator nodes = 
   root.Select("/my:myFields/my:group1/my:field1", NamespaceManager);
int myInt = 1;
while (nodes.MoveNext())
{
   nodes.Current.SetValue(myInt.ToString());
   myInt = myInt + 1;
}
Dim root As XPathNavigator = Me.CreateNavigator()
Dim nodes As XPathNodeIterator = _
   root.Select("/my:myFields/my:group1/my:field1", NamespaceManager)
Dim myInt As Integer = 1
Do While nodes.MoveNext
   nodes.Current.SetValue(myInt.ToString())
   myInt = myInt + 1
Loop

Uso de la clase XPathNavigator para obtener acceso a un origen de datos externo

Para obtener acceso a un origen de datos externo asociado al formulario, pase el nombre del origen de datos a la propiedad DataSources de la clase XmlForm . Para crear una conexión a un nuevo origen de datos externo o para ver una lista de los nombres de las conexiones existentes a orígenes de datos externos, haga clic en Conexiones de datos en la ficha Datos de la cinta de opciones.

En el siguiente ejemplo de código se muestra cómo crear un objeto XPathNavigator colocado en la raíz de un origen de datos externo denominado "CityList", mediante el método CreateNavigator, y se usa la propiedad OuterXml de la clase XPathNavigator para mostrar el XML devuelto en un cuadro de mensaje. En este ejemplo de código se supone que se ha creado una conexión de datos a una lista de nombres de ciudad que está almacenada en un origen de datos externo, como un documento XML o una lista de SharePoint, y se le ha asignado el nombre "CityList" a esta conexión de datos.

XPathNavigator myNavigator = 
   this.DataSources["CityList"].CreateNavigator();
MessageBox.Show("External data source XML: " + 
   myNavigator.OuterXml.ToString());
Dim myNavigator As XPathNavigator  = _
   Me.DataSources("CityList").CreateNavigator()
MessageBox.Show("External data source XML: " &amp; _
   myNavigator.OuterXml.ToString())

Una vez que se tiene acceso a un objeto XPathNavigator colocado en la raíz de un origen de datos externo, puede usar miembros de la clase XPathNavigator, como los métodos SelectSingleNode y SetValue, para trabajar con los datos que contiene.

Miembros del modelo de objetos de InfoPath que usan las clases XPathNavigator y XPathNodeIterator

En la tabla siguiente se ofrece un resumen de todos los miembros del espacio de nombres Microsoft.Office.InfoPath que usan la clase XPathNavigator para obtener acceso a los datos XML y manipularlos o enviarlos.

Clase primaria Miembro
AdoQueryConnection
BuildSqlFromXmlNodes (método)
AdoSubmitConnection
BuildSqlFromXmlNodes (método)
ClickedEventArgs
Source (propiedad)
ContextChangedEventArgs
Context (propiedad)
DataSource
CreateNavigator (método)
Método GetNamedNodeProperty
SetNamedNodeProperty ( método)
EmailSubmitConnection
Execute ( método)
FileQueryConnection
Execute ( método)
FileSubmitConnection
Execute ( método)
FormError
Site (propiedad)
FormErrorCollection
Agregar métodos
FormTemplate
Manifest (propiedad)
MergeEventArgs
Xml (propiedad)
SharepointListQueryConnection
Execute ( método)
Signature
SignatureBlockXmlNode (propiedad)
SignedDataBlock
SignatureContainer (propiedad)
View
Métodos GetContextNodes
Métodos SelectNodes
Métodos SelectText
WebServiceConnection
Execute ( método)
GenerateDataSetDiffGram ( método)
XmlEventArgs
OldParent ( propiedad)
Site (propiedad)
XmlForm
Propiedad MainDataSource , que devuelve un objeto DataSource que a su vez proporciona el método CreateNavigator para crear un objeto XPathNavigator situado en la raíz del documento XML subyacente del formulario (origen de datos principal).
MergeForm ( método)
XmlFormCollection
NewFromFormTemplate (método)
XmlValidatingEventArgs
Métodos ReportError

Además de los miembros del modelo de objetos de InfoPath que devuelven o aceptan un objeto XPathNavigator, los métodos siguientes devuelven una instancia de la clase XPathNodeIterator del espacio de nombres System.Xml.XPath para recorrer en iteración los nodos XML de los elementos especificados o seleccionados en una vista.

Clase primaria Miembro
View
Métodos GetContextNodes
Método GetSelectedNodes

Uso de las clases XPathNavigator y XPathNodeIterator para trabajar con los datos seleccionados en una vista

En el ejemplo siguiente, se usan los miembros de las clases XPathNavigator y XPathNodeIterator para trabajar con los datos en la secuencia siguiente:

  1. El método CreateNavigator de la clase DataSource se usa para crear una variable del objeto XPathNavigator denominada repeatingTableRow1, que de manera predeterminada se sitúa en la raíz del documento XML subyacente del formulario (el origen de datos principal).

  2. El método SelectSingleNode de la clase XPathNavigator se usa para mover la posición del objeto XPathNavigator a la primera fila de un control Tabla extensible enlazado al grupo2 en el origen de datos.

  3. La variable del objeto repeatingTableRow1 se pasa al método SelectNodes de la clase View para seleccionar los nodos de esa fila.

  4. Se declara una variable del objeto XPathNodeIterator denominada selectedNodes y el método GetSelectedNodes de la clase View se usa para rellenar el objeto XPathNodeIterator con los nodos seleccionados.

  5. La propiedad Count de la clase XPathNodeIterator se usa para mostrar el número de nodos que contiene la variable del objeto selectedNodes.

  6. Se usa un bucle For/Each para recorrer en iteración los nodos de la variable del objeto selectedNodes y mostrar información sobre cada nodo usando las propiedades Name, InnerXml y Value de la clase XPathNavigator.

// Create XPathNavigator and specify XPath for nodes.
XPathNavigator repeatingTableRow1 = 
   this.CreateNavigator().SelectSingleNode(
   "/my:myFields/my:group1/my:group2[1]", NamespaceManager);
// Select nodes in specified XPathNavigator.
CurrentView.SelectNodes(repeatingTableRow1);
// Get selected nodes.
XPathNodeIterator selectedNodes = 
   CurrentView.GetSelectedNodes();
// Display the count of selected nodes.
MessageBox.Show(selectedNodes.Count.ToString());
// Loop through collection and display information.
foreach (XPathNavigator selectedNode in selectedNodes)
{
   MessageBox.Show(selectedNode.Name);
   MessageBox.Show(selectedNode.InnerXml);
   MessageBox.Show(selectedNode.Value);
}
' Create XPathNavigator and specify XPath for nodes.
Dim repeatingTableRow1 As XPathNavigator  = _
   Me.CreateNavigator().SelectSingleNode( _
   "/my:myFields/my:group1/my:group2[1]", NamespaceManager)
' Select nodes in specified XPathNavigator.
CurrentView.SelectNodes(repeatingTableRow1)
' Get selected nodes.
Dim selectedNodes As XPathNodeIterator = _
   CurrentView.GetSelectedNodes()
' Display the count of selected nodes.
MessageBox.Show(selectedNodes.Count.ToString())
' Loop through collection and display information.
Dim selectedNode As XPathNavigator
For Each selectedNode In selectedNodes
   MessageBox.Show(selectedNode.Name)
   MessageBox.Show(selectedNode.InnerXml)
   MessageBox.Show(selectedNode.Value)
Next

Para obtener más información sobre cómo trabajar con datos XML desde plantillas de formulario de InfoPath, vea el tema sobre cómo trabajar con datos XML usando la clase XPathNavigator en plantillas de formulario de InfoPath 2007.