XPathNavigator クラスおよび XPathNodeIterator クラスを操作する方法
適用対象: InfoPath 2010 | InfoPath Forms Services | Office 2010 | SharePoint Server 2010 | Visual Studio | Visual Studio Tools for Microsoft Office
この記事の内容
XPathNavigator クラスを使用して、フォームのメイン データ ソースにアクセスする
メイン データ ソース内のフィールドを表す XML ノードを選択および設定する
XPathNavigator クラスを使用して、外部データ ソースにアクセスする
XPathNavigator クラスと XPathNodeIterator クラスを使用する InfoPath オブジェクト モデルのメンバー
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 メソッドを DataObject の DOM プロパティに代わるものと考えることができます。
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())
注意
this または Me キーワードから CreateNavigator メソッドを直接呼び出すことは、MainDataSource プロパティを使用するか (this.MainDataSource.CreateNavigator())、XmlForm クラスの DataSources プロパティに空文字列を渡して (this.DataSources[""].CreateNavigator())、CreateNavigator メソッドを呼び出すのと同じです。
メイン データ ソース内のフィールドを表す XML ノードを選択および設定する
データ ソース内のフィールドを表す単一の XML ノードを選択するには、XPathNavigator クラスの SelectSingleNode(String,IXmlNamespaceResolver) メソッドを使用します。繰り返しフィールドまたはグループを操作する場合は、XPathNavigator クラスの Select(String,IXmlNamespaceResolver) メソッドを使用します。このメソッドは、ノードのコレクションを表す XPathNodeIterator オブジェクトを返します。
単一ノードの値を選択および設定する
使用する必要があるオーバーロードされる SelectSingleNode メソッドには、XPath 式を文字列として取る xpath パラメーターと、名前空間プレフィックスを解決するための XmlNamespaceManager オブジェクトを取る resolver パラメーターがあります。フォームのメイン データ ソース内の単一ノードを選択するには、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 は、次のデータ型の 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", "http://www.w3.org/2001/XMLSchema-instance"))
node.DeleteSelf();
}
Public Sub DeleteNil(ByVal node As XPathNavigator)
If (node.MoveToAttribute( _
"nil", "http://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 & 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: " & _
myNavigator.OuterXml.ToString())
外部データ ソースのルートに置かれる XPathNavigator オブジェクトにアクセスした後は、SelectSingleNode および SetValue メソッドなど、XPathNavigator クラスのメンバーを使用して、そのデータ ソース内のデータを操作できます。
XPathNavigator クラスと XPathNodeIterator クラスを使用する InfoPath オブジェクト モデルのメンバー
次の表に、XPathNavigator クラスを使用して XML データのアクセス、操作、および送信を行う Microsoft.Office.InfoPath 名前空間のすべてのメンバーの概要を示します。
親クラス |
メンバー |
---|---|
BuildSqlFromXmlNodes メソッド |
|
BuildSqlFromXmlNodes メソッド |
|
Source プロパティ |
|
Context プロパティ |
|
CreateNavigator メソッド |
|
GetNamedNodeProperty メソッド |
|
SetNamedNodeProperty メソッド |
|
Execute メソッド |
|
Execute メソッド |
|
Execute メソッド |
|
Site プロパティ |
|
Add メソッド |
|
Manifest プロパティ |
|
Xml プロパティ |
|
Execute メソッド |
|
SignatureBlockXmlNode プロパティ |
|
SignatureContainer プロパティ |
|
GetContextNodes メソッド |
|
SelectNodes メソッド |
|
SelectText メソッド |
|
Execute メソッド |
|
OldParent プロパティ |
|
Site プロパティ |
|
MainDataSource プロパティ。DataSource オブジェクトを返します。このオブジェクトは、フォームの基になる XML ドキュメント (メイン データ ソース) のルートに置かれる XPathNavigator オブジェクトを作成する CreateNavigator メソッドを備えます。 |
|
MergeForm メソッド |
|
NewFromFormTemplate メソッド |
|
ReportError メソッド |
XPathNavigator オブジェクトを返すか受け取る InfoPath オブジェクト モデル メンバーに加え、次のメソッドでは、ビューで指定または選択された項目の XML ノードに対して反復処理を行うため、System.Xml.XPath 名前空間の XPathNodeIterator クラスのインスタンスを返します。
親クラス |
メンバー |
---|---|
GetContextNodes メソッド |
|
GetSelectedNodes メソッド |
XPathNavigator クラスと XPathNodeIterator クラスを使用して、ビューで選択されたデータを操作する
次の例では、XPathNavigator クラスと XPathNodeIterator クラスのメンバーを使用して、次のシーケンスのフォーム データを操作します。
DataSource クラスの CreateNavigator メソッドを使用して、repeatingTableRow1 という名前の XPathNavigator オブジェクト変数を作成します。このオブジェクト変数は、既定では、フォームの基になる XML ドキュメント (メイン データ ソース) のルートに置かれます。
XPathNavigator クラスの SelectSingleNode メソッドを使用して、XPathNavigator オブジェクトの位置を、データ ソースの group2 にバインドされた [繰り返しテーブル] コントロールの先頭行に移動します。
repeatingTableRow1 オブジェクト変数を View クラスの SelectNodes メソッドに渡し、その行のノードを選択します。
selectedNodes という名前の XPathNodeIterator オブジェクト変数を宣言し、View クラスの GetSelectedNodes メソッドを使用して、XPathNodeIterator オブジェクトに選択されたノードを入力します。
XPathNodeIterator クラスの Count プロパティを使用して、selectedNodes オブジェクト変数に含まれているノード数を表示します。
For/Each ループを使用して、selectedNodes オブジェクト変数のノードに対して反復処理を行い、XPathNavigator クラスの Name、InnerXml、および 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 データの操作方法の詳細については、「Working with XML Data Using the XPathNavigator Class in InfoPath 2007 Form Templates (英語)」を参照してください。