Поделиться через


Работа с классами XPathNavigator и XPathNodeIterator

Для доступа к XML-данным и управления ими в источниках данных шаблона формы многие члены объектной модели управляемого кода, предоставляемой пространством имен Microsoft.Office.InfoPath , создают или могут быть переданы экземпляр класса XPathNavigatorSystem.Xml. Пространство имен XPath . После получения доступа к объекту XPathNavigator, возвращенному элементом объектной модели InfoPath, можно использовать свойства и методы класса XPathNavigator для работы с данными.

Наиболее часто используемым членом пространства имен Microsoft.Office.InfoPath , использующим класс XPathNavigator , является метод CreateNavigator класса DataSource , который позволяет работать с сохраненными данными, представленными объектом DataSource . Метод CreateNavigator создает объект XPathNavigator, располагающийся в корне источника данных, представленного объектом DataSource.

Совет

При наличии опыта использования MSXML5 из скрипта для работы с данными в Microsoft InfoPath 2003 можно рассмотреть вариант применения метода CreateNavigator в качестве замены свойства DOM для DataObject.

Использование класса XPathNavigator для доступа к основному источнику данных формы

Чтобы получить доступ к main источнику данных формы, вызовите метод CreateNavigator непосредственно из этого ключевое слово (C#) или Me (Visual Basic). В следующем примере создается объект XPathNavigator, расположенный в корне основного источника данных, с помощью метода CreateNavigator, после чего используется свойство OuterXml класса XPathNavigator для отображения XML-данных, возвращаемых в окне сообщения.

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())

Примечание.

Вызов метода CreateNavigator непосредственно из этого или Me ключевое слово эквивалентен вызову метода CreateNavigator с помощью свойства MainDataSource ( this.MainDataSource.CreateNavigator()) или путем передачи пустой строки в свойство DataSources класса XmlForm ( this.DataSources[""].CreateNavigator()).

Выбор и установка XML-узлов для полей в основном источнике данных

Чтобы выбрать один XML-узел для поля в источнике данных, используйте метод SelectSingleNode(String,IXmlNamespaceResolver) класса XPathNavigator . Если вы хотите работать с набором повторяющихся полей или повторяющихся групп, используйте метод Select(String,IXmlNamespaceResolver) класса XPathNavigator . Этот метод возвращает объект XPathNodeIterator , представляющий коллекцию узлов.

Выбор и установка значения для отдельного узла

Перегруженный метод SelectSingleNode , который необходимо использовать, имеет параметр xpath , который принимает выражение XPath в виде строки, и параметр сопоставителя , который принимает объект XmlNamespaceManager для разрешения префиксов пространства имен. Чтобы выбрать один узел в main источнике данных формы, передайте выражение XPath, указывающее поле или группу, которые нужно выбрать для параметра xpath, а также объект XmlNamespaceManager, возвращаемый свойством NamespaceManager объекта XmlForm. Возвращаемый объект XmlNamespaceManager инициализируется во время загрузки с использованием всех пространств имен, определенных в файле определения шаблона формы (XSF).

Совет

Чтобы наиболее быстро создать выражение XPath для выбора узла в источнике данных формы, щелкните правой кнопкой мыши поле или группу в области задач Поля и выберите пункт Копировать XPath. Чтобы создать и проверить созданные вручную выражения XPath для доступа к узлам в сложной схеме XML или схеме XML с большим числом уровней вложения, добавьте в форму элемент управления Поле выражения, укажите в нем выражение XPath и выполните предварительный просмотр формы для отображения результатов.

В следующем примере метод SelectSingleNode используется для выбора одного узла для EmailAlias поля. Затем используется метод SetValue класса XPathNavigator и свойство UserName класса User , чтобы задать для поля псевдоним текущего пользователя.

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())

Сведения о создании выражений XPath см. в справочнике по XPath на сайте MSDN и рекомендации по языку XML-пути (XPath) версии 1.0 W3C.

Установка значения для узла с атрибутом xsi:nil

Для некоторых типов данных при попытке задать значение пустого поля программным способом возникает ошибка "Проверка схемы обнаружила ошибки, отличные от типа данных". Обычно причина этой ошибки заключается в том, что для элемента задано значение true для атрибута xsi:nil. Этот параметр можно обнаружить при проверке базового XML-элемента для пустого поля формы. Например, атрибуту xsi:nil XML-фрагмента для следующего пустого поля даты присвоено значение true.

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

Если атрибут xsi:nil имеет значение true, это означает, что элемент присутствует, но не имеет значения, или, другими словами, имеет значение NULL. Если вы попытаетесь программно задать значение такого узла, InfoPath отображает сообщение "Проверка схемы обнаружила ошибки, не связанные с типом данных", так как в настоящее время элемент помечается как null . В InfoPath атрибуту xsi:nil присваивается значение true для полей null следующих типов данных:

  • Целое число (целое число)

  • Decimal (double)

  • Дата (дата)

  • Время (время)

  • Дата и время (dateTime)

Чтобы предотвратить эту ошибку, код должен протестировать атрибут xsi:nil и, если он присутствует, удалить его перед установкой значения узла. Следующая подпрограмма принимает объект XpathNavigator , расположенный на узле, который требуется задать, проверяет атрибут nil , а затем удаляет его, если он существует.

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

Эту подпрограмму можно вызвать перед попыткой установить поле типа данных, который может содержать атрибут xsi:nil, как показано в следующем примере, в котором устанавливается поле даты.

// 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)

Примечание.

Хотя реализация объекта XPathNavigator в InfoPath предоставляет метод SetTypedValue , который используется для задания узла с помощью значения определенного типа, InfoPath не реализует этот метод. Вместо него необходимо использовать метод SetValue, в который передается строковое значение в формате, соответствующем типу данных узла.

Выбор и установка набора повторяющихся узлов

Чтобы указать набор повторяющихся полей или групп с неопределенным числом, используйте метод Select класса XPathNavigator . Этот метод возвращает объект XPathNodeIterator, который можно использовать для итерации по указанной коллекции узлов.

В следующем примере предполагается, что шаблон формы содержит маркированный список или аналогичный повторяющийся элемент управления, привязанный к повторяющимся элементу с именем field1. XPath поля передается в метод Select , а возвращенный XPathNodeIterator назначается переменной nodes . Метод MoveNext используется для итерации по коллекции узлов, а свойство Current — для возврата объекта XPathNavigator , расположенного на текущем узле. Наконец, используйте свойство Value для получения и отображения значения каждого повторяющегося поля.

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)

В предыдущем примере обрабатываются строковые значения в заданном повторяющемся поле. Однако если поле содержит числовые значения, можно использовать аналогичный код для итерации по значениям поля и выполнения арифметических операций, таких как вычисление суммы или средней величины всех значений.

Также вместо использования свойства Value для извлечения значения каждого экземпляра повторяющегося поля можно использовать метод SetValue для итерации по полям и установки их значений, как показано в следующем примере.

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

Использование класса XPathNavigator для доступа к внешнему источнику данных

Чтобы получить доступ к внешнему источнику данных, связанному с формой, передайте имя источника данных в свойство DataSources класса XmlForm . Чтобы создать подключение к новому внешнему источнику данных или просмотреть имена существующих подключений к внешнему источнику данных, выберите элемент Подключения к данным на вкладке Данные ленты.

В следующем примере кода описывается создание объекта XPathNavigator, расположенного в корне внешнего источника данных "CityList", с помощью метода CreateNavigator с последующим использованием свойства OuterXml класса XPathNavigator для отображения XML-данных, возвращаемых в окне сообщения. В этом примере кода предполагается, что создано подключение к данным списка городов, который хранится во внешнем источнике данных, например, в XML-документе или списке SharePoint, и этому подключению присвоено имя "CityList".

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())

После получения доступа к объекту XPathNavigator, расположенному в корне внешнего источника данных, можно использовать члены класса XPathNavigator, такие как методы SelectSingleNode и SetValue, для работы с содержащимися в нем данными.

Элементы объектной модели InfoPath, использующие классы XPathNavigator и XPathNodeIterator

В следующей таблице приведены обобщенные сведения обо всех элементах пространства имен Microsoft.Office.InfoPath, использующих класс XPathNavigator для доступа к XML-данным, управления ими и их отправки.

Родительский класс Элемент
AdoQueryConnection
Метод BuildSqlFromXmlNodes
AdoSubmitConnection
Метод BuildSqlFromXmlNodes
ClickedEventArgs
Свойство Source
ContextChangedEventArgs
Свойство Context
DataSource
Метод CreateNavigator
Метод GetNamedNodeProperty
Метод SetNamedNodeProperty
EmailSubmitConnection
Метод Execute
FileQueryConnection
Метод Execute
FileSubmitConnection
Метод Execute
FormError
Свойство сайта
FormErrorCollection
Добавление методов
FormTemplate
Свойство Manifest
MergeEventArgs
Свойство Xml
SharepointListQueryConnection
Метод Execute
Подпись
Свойство SignatureBlockXmlNode
SignedDataBlock
Свойство SignatureContainer
Просмотр
Методы GetContextNodes
Методы SelectNodes
Методы SelectText
WebServiceConnection
Метод Execute
Метод GenerateDataSetDiffGram
XmlEventArgs
Свойство OldParent
Свойство сайта
Xmlform
Свойство MainDataSource, которое возвращает объект DataSource, который, в свою очередь, предоставляет метод CreateNavigator для создания объекта XPathNavigator, расположенного в корне базового XML-документа формы (main источник данных).
Метод MergeForm
XmlFormCollection
Метод NewFromFormTemplate
XmlValidatingEventArgs
Методы ReportError

В дополнение к элементам объектной модели InfoPath, возвращающим или принимающим объект XPathNavigator, следующие методы возвращают экземпляр класса XPathNodeIterator пространства имен System.Xml.XPath для прохода по XML-узлам элементов, указанных или выбранных в представлении.

Родительский класс Элемент
Просмотр
Методы GetContextNodes
Метод GetSelectedNodes

Использование классов XPathNavigator и XPathNodeIterator для работы с данными, выбранными в представлении

В следующем примере используются элементы обоих классов XPathNavigator и XPathNodeIterator для работы с данными форм в следующей последовательности:

  1. Метод CreateNavigator класса DataSource используется для создания объектной переменной XPathNavigator с именем repeatingTableRow1, которая по умолчанию располагается в корне базового XML-документа формы (main источник данных).

  2. Метод SelectSingleNode класса XPathNavigator используется для перемещения позиции объекта XPathNavigator в первую строку элемента управления Repeating Table , привязанного к group2 в источнике данных.

  3. Объектная переменная repeatingTableRow1 передается методу SelectNodes класса View для выбора узлов в этой строке.

  4. Объявляется объектная переменная XPathNodeIterator с именем selectedNodes, а используется метод GetSelectedNodes класса View , заполняющий объект XPathNodeIterator выбранными узлами.

  5. Свойство Count класса XPathNodeIterator используется для отображения количества узлов, содержащихся в переменной объекта selectedNodes.

  6. Цикл For/Each используется для прохода по узлам объектной переменной selectedNodes и отображения сведений о каждом узле с помощью свойств Name, InnerXml и Value класса 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

Дополнительные сведения о работе с XML-данными из шаблонов форм InfoPath см. в статье Работа с XML-данными с помощью класса XPathNavigator в шаблонах форм InfoPath 2007.