InfoPath 表單產生的 XML 具有深層巢狀、重複區塊(Repeating Section/Table)特性。常見需求:根據子節點條件篩選父層級項目,例如「找出所有 `c2='書'` 的項目對應的 `c1` 值」。
<Table1>
<a></a>
<b></b>
<c> <!-- 重複群組 -->
<c1>1</c1>
<c2>書</c2>
<c3>好</c3>
</c>
<c>
<c1>2</c1>
<c2>書</c2>
<c3></c3>
</c>
<c>
<c1>3</c1>
<c2>書</c2>
<c3>好</c3>
</c>
<c>
<c1>4</c1>
<c2>4</c2>
<c3>4</c3>
</c>
</Table1>
關鍵在於使用 ..(父節點軸)在謂詞中向上導航,再向下選取兄弟節點。
// 方式 1:單引號包裹字串常值
IXMLDOMNodeList nodes = xdoc.DOM.SelectNodes("//Table1/b/c/c1[../c2 = '書']");
// 方式 2:雙引號需跳脫
IXMLDOMNodeList nodes = xdoc.DOM.SelectNodes("//Table1/b/c/c1[../c2 = \"書\"]");
解析:
IXMLDOMNodeList nodes = xdoc.DOM.SelectNodes(
"//Table1/b/c/c1[../c2 = '書' and ../c3 = '好']");
結果僅包含 `c1=1` 與 `c1=3` 兩個節點。
// c2='書' 或 c2='筆'
IXMLDOMNodeList nodes = xdoc.DOM.SelectNodes(
"//Table1/b/c/c1[../c2 = '書' or ../c2 = '筆']");
using System;
using System.Xml;
using System.Xml.XPath;
using MSXML2; // 需參考 Microsoft XML, v6.0 (msxml6.dll)
public class InfoPathXmlQuery
{
public static void Main()
{
string xml = @"1 書 好
2 書
3 書 好
4 4 4
";
var doc = new XmlDocument();
doc.LoadXml(xml);
// 使用 System.Xml.XPath (標準 .NET)
var navigator = doc.CreateNavigator();
var iterator = navigator.Select("//Table1/b/c/c1[../c2 = '書' and ../c3 = '好']");
Console.WriteLine("符合 c2='書' 且 c3='好' 的 c1 值:");
while (iterator.MoveNext())
{
Console.WriteLine(iterator.Current.Value); // 輸出: 1, 3
}
// 若在 InfoPath 表單程式碼中 (使用 MSXML DOM)
// IXMLDOMNodeList list = thisXDocument.DOM.SelectNodes(...);
}
}
| 軸 | 意義 | 範例 |
|---|---|---|
| `child::` / (預設) | 子節點 | `c/c1` |
| `parent::` / `..` | 父節點 | `../c2` |
| `ancestor::` | 所有祖先 | `ancestor::Table1` |
| `descendant::` / `//` | 所有後代 | `//c1` |
| `following-sibling::` | 後續同層節點 | `following-sibling::c2` |
| `preceding-sibling::` | 前序同層節點 | `preceding-sibling::c1` |
掌握 ../ 父節點軸在謂詞中的運用,是查詢 InfoPath 等巢狀重複結構 XML 的核心關鍵。配合 `and`/`or` 邏輯組合,即可靈活實現「依子節點條件篩選父群組」等進階查詢需求。