共用方式為


使用 XPathNavigator 和 XPathNodeIterator 類別

若要存取和管理表單範本資料來源中的 XML 資料,Microsoft.Office.InfoPath 命名空間所提供的許多 Managed 程式碼物件模型成員可以建立 System.Xml.XPath 命名空間的 XPathNavigator 類別執行個體,或將此執行個體傳遞給這些成員。 在您存取 InfoPath 物件模型成員所傳回的 XPathNavigator 物件之後,就可以使用 XPathNavigator 類別的屬性和方法來處理資料。

最常用的 Microsoft.Office.InfoPath 命名空間成員 (使用 XPathNavigator 類別) 是 DataSource 類別的 CreateNavigator 方法,此方法可讓您使用 DataSource 物件所表示的儲存資料。 CreateNavigator 方法會建立 XPathNavigator 物件 (位於 DataSource 物件所表示之資料來源的根目錄)。

提示

[!秘訣] 如果您熟悉從指令碼使用 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())

注意事項

直接從 thisMe 關鍵詞呼叫 CreateNavigator 方法,相當於使用 MainDataSource 屬性 () this.MainDataSource.CreateNavigator() 呼叫 CreateNavigator 方法,或將空字串傳遞至 XmlForm 類別的 DataSources 屬性, () this.DataSources[""].CreateNavigator()

為主要資料來源中的欄位選取並設定 XML 節點

若要為資料來源中的欄位選取單一 XML 節點,請使用 XPathNavigator 類別的 SelectSingleNode(String,IXmlNamespaceResolver) 方法。 如果要處理一組重複欄位或重複群組,請使用 XPathNavigator 類別的 Select(String,IXmlNamespaceResolver) 方法。 此方法會傳回表示節點集合的 XPathNodeIterator 物件。

選取並設定單一節點的值

您必須使用的多載 SelectSingleNode 方法具有採用 XPath 運算式做為字串的 xpath 參數,以及採用 XmlNamespaceManager 物件來解析命名空間前置詞的解析程式參數。 若要在表單體的主要數據源中選取單一節點,請傳入 XPath 運算式,指定您要為 xpath 參數選取的欄位或群組,以及 XmlForm 物件的 NamespaceManager 屬性所傳回的 XmlNamespaceManager 物件。 此傳回的 XmlNamespaceManager 物件會在載入時,以表單範本的表單定義檔案 (.xsf) 所定義的所有命名空間進行初始化。

提示

[!秘訣] 為了在表單資料來源中選取節點而建立的 XPath 運算式,有個最簡單的建立方式就是,在 [欄位] 工作窗格中以滑鼠右鍵按一下欄位或群組,然後按一下 [複製 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 路徑語言 (XPath) 版本 1.0 W3C 建議 (可能為英文網頁)

設定具有 xsi:nil 屬性之節點的值

對於特定數據類型,嘗試以程式設計方式設定空白欄位的值會引發「架構驗證發現非數據類型錯誤」錯誤。此錯誤的一般原因是元素的 xsi:nil 屬性設定為 true。 如果檢查表單中此空白欄位的基礎 XML 元素,就會看到此設定。 例如,在下列空白的 Date 欄位之 XML 片段中將 xsi:nil 屬性設為 true

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

如果 xsi:nil 屬性設為 true,這表示該元素雖存在,但沒有值,也就是說,即為 null。 如果嘗試以程式設計方式設定此類節點的值,InfoPath 就會顯示「結構描述驗證找到非資料類型的錯誤」訊息,因為該元素目前標示為 null。 對於下列資料類型的 null 欄位,InfoPath 會將 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

您可以先呼叫此副程式,然後再嘗試對可能具有 xsi:nil 屬性之資料類型的欄位加以設定,如下列設定 Date 欄位的範例所示。

// 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 方法來建立 XPathNavigator 物件 (位於名為 "CityList" 之資料來源的根目錄),然後使用 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 物件的存取權,就可以使用 XPathNavigator 類別的成員 (例如 SelectSingleNodeSetValue 方法),處理該物件包含的資料。

使用 XPathNavigator 和 XPathNodeIterator 類別的 InfoPath 物件模型成員

下表將提供使用 XPathNavigator 類別來存取、管理或送出 XML 資料之所有 Microsoft.Office.InfoPath 命名空間成員的摘要。

父類別 Member
AdoQueryConnection
BuildSqlFromXmlNodes 方法
AdoSubmitConnection
BuildSqlFromXmlNodes 方法
ClickedEventArgs
Source 屬性
ContextChangedEventArgs
Context 屬性
DataSource
CreateNavigator 方法
GetNamedNodeProperty 方法
SetNamedNodeProperty 方法
EmailSubmitConnection
Execute 方法
FileQueryConnection
Execute 方法
FileSubmitConnection
Execute 方法
FormError
Site 屬性
FormErrorCollection
新增 方法
FormTemplate
指令清單 屬性
MergeEventArgs
Xml 屬性
SharepointListQueryConnection
Execute 方法
簽章
SignatureBlockXmlNode 屬性
SignedDataBlock
SignatureContainer 屬性
View
GetContextNodes 方法
SelectNodes 方法
SelectText 方法
WebServiceConnection
Execute 方法
GenerateDataSetDiffGram 方法
XmlEventArgs
OldParent 屬性
Site 屬性
XmlForm
MainDataSource 屬性,會傳回 DataSource 物件,該對象接著會提供 CreateNavigator 方法來建立位於表單基礎 XML 檔根目錄的 XPathNavigator 物件, (主要數據源) 。
MergeForm 方法
XmlFormCollection
NewFromFormTemplate 方法
XmlValidatingEventArgs
ReportError 方法

除了傳回或接受 XPathNavigator 物件的 InfoPath 物件模型成員以外,下列方法會傳回 System.Xml.XPath 命名空間之 XPathNodeIterator 類別的執行個體,以便逐一查看檢視中指定或選取之項目的 XML 節點。

父類別 Member
View
GetContextNodes 方法
GetSelectedNodes 方法

使用 XPathNavigator 和 XPathNodeIterator 類別來處理檢視中選取的資料

下列範例會按照下列順序,使用 XPathNavigatorXPathNodeIterator 類別的成員來處理表單資料:

  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 類別的 NameInnerXmlValue 屬性顯示每個節點的相關資訊。

// 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 資料(可能為英文網頁)。