XPathNavigator クラスおよび XPathNodeIterator クラスを操作する

フォーム テンプレートのデータ ソースの XML データにアクセスして操作するには、Microsoft.Office.InfoPath 名前空間によって提供されるマネージ コード オブジェクト モデルの多くのメンバーは、 System.Xml.XPath 名前空間の XPathNavigator クラスのインスタンスを作成するか、そのインスタンスが渡されます。 InfoPath オブジェクト モデルのメンバーから返される XPathNavigator オブジェクトにアクセスした後、 XPathNavigator クラスのプロパティとメソッドを使用してデータを操作できます。

XPathNavigator クラスを使用する Microsoft.Office.InfoPath 名前空間の最も頻繁に使用されるメンバーは、DataSource クラスの CreateNavigator メソッドであり、DataSource オブジェクトによって表される格納されたデータを操作できます。 CreateNavigator メソッドは、DataSource オブジェクトによって表されるデータ ソースのルートに配置された XPathNavigator オブジェクトを作成します。

ヒント

スクリプトから MSXML5 を使用して Microsoft InfoPath 2003 のデータを操作する方法に慣れている場合は、 CreateNavigator メソッドを DataObjectDOM プロパティに代わるものと考えることができます。

XPathNavigator クラスを使用して、フォームのメイン データ ソースにアクセスする

フォームのメイン データ ソースにアクセスするには、 this (C#) または Me (Visual Basic) キーワードから CreateNavigator メソッドを直接呼び出します。 次の例では、 CreateNavigator メソッドを使用して、メイン データ ソースのルートに置かれる XPathNavigator オブジェクトを作成し、 XPathNavigator クラスの OuterXml プロパティを使用して、返される 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())

注:

このまたは Me キーワード (keyword)から CreateNavigator メソッドを直接呼び出すことは、MainDataSource プロパティ ( ) を使用するか、または XmlForm クラス ( this.DataSources[""].CreateNavigator()this.MainDataSource.CreateNavigator()) の DataSources プロパティに空の文字列を渡すことによって CreateNavigator メソッドを呼び出すことと同じです。

メイン データ ソース内のフィールドを表す XML ノードを選択および設定する

データ ソース内のフィールドを表す単一の XML ノードを選択するには、 XPathNavigator クラスの SelectSingleNode(String,IXmlNamespaceResolver) メソッドを使用します。 一連の繰り返しフィールドまたはグループを操作する場合は、 XPathNavigator クラスの Select(String,IXmlNamespaceResolver) メソッドを使用します。 このメソッドは、ノードのコレクションを表す XPathNodeIterator オブジェクトを返します。

単一ノードの値を選択および設定する

使用する必要があるオーバーロードされた SelectSingleNode メソッドには、XPath 式を文字列として受け取る xpath パラメーターと、名前空間プレフィックスを解決するために XmlNamespaceManager オブジェクトを受け取るリゾルバー パラメーターがあります。 フォームのメイン データ ソース内の 1 つのノードを選択するには、xpath パラメーターに選択するフィールドまたはグループを指定する XPath 式と、XmlForm オブジェクトの NamespaceManager プロパティによって返される XmlNamespaceManager オブジェクトを渡します。 返される XmlNamespaceManager オブジェクトは、読み込み時に、フォーム テンプレートのフォーム定義ファイル (.xsf) によって定義されるすべての名前空間で初期化されます。

ヒント

[!ヒント] フォームのデータ ソース内のノードを選択する XPath 式を最も簡単に作成するには、[ フィールド] 作業ウィンドウ内でフィールドまたはグループを右クリックし、[ XPath のコピー] をクリックします。 複雑な、または深い入れ子になった XML スキーマ内のノードにアクセスするための手動編集 XPath 式を作成してテストするには、フォームに 式ボックス コントロールを追加し、フォームをプレビューして結果を表示します。

次の例では 、SelectSingleNode メソッドを 使用して、フィールドの単一ノードを EmailAlias 選択します。 さらに、 XPathNavigator クラスの SetValue メソッドと User クラスの UserName プロパティを使用して、そのフィールドの値を現在のユーザーのエイリアスに設定します。

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 式の作成方法については、MSDN の「XPath リファレンス」と、「XML Path Language (XPath) Version 1.0 W3C Recommendation」を参照してください。

xsi:nil 属性を持つノードの値を設定する

特定のデータ型の場合、空白フィールドの値をプログラムで設定しようとすると、"スキーマ検証でデータ型以外のエラーが見つかりました" というエラーが発生します。通常、このエラーの原因は、 要素に xsi:nil 属性が true に設定されていること です。 フォーム内の空白フィールドの基になる XML 要素を調べると、この設定を確認できます。 たとえば、次の空白の Date フィールドの XML フラグメントには 、xsi:nil 属性が true に設定 されています

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

xsi:nil 属性が true に設定されている場合、要素は存在するが値を持たないか、つまり null であることを示します。 このようなノードの値をプログラムで設定しようとすると、要素が現在 null としてフラグが設定されているため、InfoPath によって "スキーマ検証でデータ型以外の型エラーが検出されました" というメッセージが表示されます。 InfoPath は、次のデータ型の null フィールドに対して xsi:nil 属性を true に設定します。

  • Whole Number (integer)

  • Decimal (double)

  • Date (date)

  • Time (time)

  • Date and Time (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

たとえば、次の例では Date フィールドを設定していますが、この例に示すように、 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)

注:

[!メモ] InfoPath の XPathNavigator オブジェクトの実装は、 SetTypedValue メソッド (特定の型の値を使用してノードを設定するために使用) を公開していますが、InfoPath は、このメソッドを実装していません。 代わりに、 SetValue メソッドを使用して、ノードのデータ型に適切な形式の文字列値を渡す必要があります。

繰り返しノードを選択および設定する

繰り返される回数が不確かなフィールドまたはグループの一式を指定するには、XPathNavigator クラスの Select メソッドを使用します。 このメソッドから返される 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 クラスを使用して、外部データ ソースにアクセスする

フォームに関連付けられている外部データ ソースにアクセスするには、データ ソースの名前を XmlForm クラスの DataSources プロパティに渡します。 新しい外部データ ソースへの接続を作成したり、既存の外部データ ソース接続の名前の一覧を表示したりするには、リボンの [ データ] タブの [ データ接続] をクリックします。

次のコード サンプルでは、 CreateNavigator メソッドを使用して外部データ ソース "CityList" のルートに置かれる XPathNavigator オブジェクトを作成し、 XPathNavigator クラスの OuterXml プロパティを使用して、返される 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 オブジェクトにアクセスした後は、 SelectSingleNode および SetValue メソッドなど、 XPathNavigator クラスのメンバーを使用して、そのデータ ソース内のデータを操作できます。

XPathNavigator クラスと XPathNodeIterator クラスを使用する InfoPath オブジェクト モデルのメンバー

次の表に、 XPathNavigator クラスを使用して XML データのアクセス、操作、および送信を行う Microsoft.Office.InfoPath 名前空間のすべてのメンバーの概要を示します。

親クラス メンバー
AdoQueryConnection
BuildSqlFromXmlNodes メソッド
AdoSubmitConnection
BuildSqlFromXmlNodes メソッド
ClickedEventArgs
Source プロパティ
ContextChangedEventArgs
Context プロパティ
DataSource
CreateNavigator メソッド
GetNamedNodeProperty メソッド
SetNamedNodeProperty メソッド
EmailSubmitConnection
Execute メソッド
FileQueryConnection
Execute メソッド
FileSubmitConnection
Execute メソッド
FormError
Site プロパティ
FormErrorCollection
Add メソッド
FormTemplate
Manifest プロパティ
MergeEventArgs
Xml プロパティ
SharepointListQueryConnection
Execute メソッド
Signature
SignatureBlockXmlNode プロパティ
SignedDataBlock
SignatureContainer プロパティ
View
GetContextNodes メソッド
SelectNodes メソッド
SelectText メソッド
WebServiceConnection
Execute メソッド
GenerateDataSetDiffGram メソッド
XmlEventArgs
OldParent プロパティ
Site プロパティ
XmlForm
MainDataSource プロパティ。 DataSource オブジェクトを返します。このオブジェクトは、フォームの基になる XML ドキュメント (メイン データ ソース) のルートに置かれる XPathNavigator オブジェクトを作成する CreateNavigator メソッドを備えます。
MergeForm メソッド
XmlFormCollection
NewFromFormTemplate メソッド
XmlValidatingEventArgs
ReportError メソッド

XPathNavigator オブジェクトを返すか受け取る InfoPath オブジェクト モデル メンバーに加え、次のメソッドでは、ビューで指定または選択された項目の XML ノードに対して反復処理を行うため、 System.Xml.XPath 名前空間の XPathNodeIterator クラスのインスタンスを返します。

親クラス メンバー
View
GetContextNodes メソッド
GetSelectedNodes メソッド

XPathNavigator クラスと XPathNodeIterator クラスを使用して、ビューで選択されたデータを操作する

次の例では、 XPathNavigator クラスと XPathNodeIterator クラスのメンバーを使用して、次のシーケンスのフォーム データを操作します。

  1. DataSource クラスの CreateNavigator メソッドを使用して、 repeatingTableRow1 という名前の XPathNavigator オブジェクト変数を作成します。このオブジェクト変数は、既定では、フォームの基になる XML ドキュメント (メイン データ ソース) のルートに置かれます。

  2. XPathNavigator クラスの SelectSingleNode メソッドを使用して、 XPathNavigator オブジェクトの位置を、データ ソースの group2 にバインドされた [ 繰り返しテーブル] コントロールの先頭行に移動します。

  3. repeatingTableRow1 オブジェクト変数を View クラスの SelectNodes メソッドに渡し、その行のノードを選択します。

  4. selectedNodes という名前の XPathNodeIterator オブジェクト変数を宣言し、 View クラスの GetSelectedNodes メソッドを使用して、 XPathNodeIterator オブジェクトに選択されたノードを入力します。

  5. XPathNodeIterator クラスの Count プロパティを使用して、 selectedNodes オブジェクト変数に含まれているノード数を表示します。

  6. For/Each ループを使用して、selectedNodes オブジェクト変数のノードに対して反復処理を行い、 XPathNavigator クラスの NameInnerXml、および Value プロパティを使用して各ノードに関する情報を表示します。

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

InfoPath フォーム テンプレートからの XML データの操作方法の詳細については、「InfoPath 2007 フォーム テンプレートで XPathNavigator クラスを使用して XML データを操作する」を参照してください。