2010-12-02 22 views
1

使用參數創建x路徑的最佳做法是什麼?Xml:使用參數創建x路徑的最佳實踐

我必須選擇XML節點,在屬性有確切的價值,是這樣的:

XmlNode node = parentNode.SelectSingleNode(
    string.Format("./field1/field2[@attributeName='{0}']", valueRequired)); 
+0

您對這類代碼的問題是valueRequired需要正確轉義以確保它不會破壞XPATH語法。 Marc Gravell的主張沒有這個問題 - 雖然我是XPATH的忠實粉絲:) – 2010-12-02 07:41:31

+0

我們有參數化的SQL查詢,但仍然沒有參數化XPath ... – 2010-12-02 16:20:58

回答

0

XPath引擎的主機可以創建變量是上下文的一部分。提供此功能的主機示例是XSLT

在XSLT人會簡單地寫:

field1/field2[@attributeName=$valueRequired]" 

一個在.NET創建的XPath變量和函數的方式是使用XsltContext類及其方法ResolveVariable()ResolveFunction()

另一件要記住的事情:切勿盲目地將用戶輸入插入到XPath表達式的「骨架」中。請注意0​​的可能性。

2

這取決於valueRequired是否曾經打算有這樣一個討厭的值作爲'。但對於應該可以正常工作的簡單值。

否則,LINQ到XML是相當不錯的:

// where parentNode is XElement 
var node = (from el in parentNode.Elements("field1").Elements("field2") 
      where (string) el.Attribute("attributeName") == valueRequired 
      select el).FirstOrDefault(); 

(更換(string)視需要與其他類型)

下面是使用LINQ在一個XmlElement的類似的東西:

var parentNode = node.SelectNodes("./field1/field2[@attributeName]") 
     .Cast<XmlElement>() 
     .Where(el => el.GetAttribute("attributeName") == valueRequired) 
     .FirstOrDefault(); 

其他選項(沒有任何 LINQ)只是用foreach手動循環。

+0

是否有可能使用舊的XmlDocument代碼做類似的事情,或者您是否建議將其重寫爲XDocument/XElement? – 2010-12-02 07:01:39

+0

@Andrew - 我將編輯以顯示與XmlDocument類似的東西 – 2010-12-02 07:02:42

1

有時候X-Path符號比LINQ更短更清晰,在這種情況下,我寧願使用X-Path而不是LINQ。在你的情況中,因爲你已經知道屬性類型,所以應該很容易決定是否包含引號。

你應該考慮使用System.Xml.XPath的元素,通過以下方法:

XmlReader xmlReader = XmlReader.Create(xmlFile); 
XElement xmlRoot = XElement.Load(xmlReader); 
xmlReader.Close(); 
IEnumerable<XElement> nodes = 
    xmlRoot.XPathSelectElements(string.Format("./field1/field2[@attributeName='{0}']", valueRequired)); 
1

你的做法是好的。你應該知道可以在valueRequired。如果你不信任它的源代碼,那麼就像使用任何不可信的數據一樣進行清理。

而且,你不需要啓動相對路徑與./,只使用:

field1/field2[@attributeName='{0}']