我需要一個關於如何在Xml中使用System.Linq.Dynamic的基本示例。這裏是一個有效的聲明我要轉換爲動態的LINQ:動態Linq到Xml示例
XElement e = XElement.Load(new XmlNodeReader(XmlDoc));
var results =
from r in e.Elements("TABLES").Descendants("AGREEMENT")
where (string)r.Element("AGRMNT_TYPE_CODE") == "ISDA"
select r.Element("DATE_SIGNED");
foreach (var x in results)
{
result = x.Value;
break;
}
下面是我使用的方法:
string whereClause = "(\"AGRMNT_TYPE_CODE\") == \"ISDA\"";
string selectClause = "(\"DATE_SIGNED\")";
var results = e.Elements("TABLES").Descendants<XElement>("AGREEMENT").
AsQueryable<XElement>().
Where<XElement>(whereClause).
Select(selectClause);
foreach (var x in results)
{
result = (string)x;
break;
}
它的執行沒有錯誤,但不會產生任何結果。
我試圖代碼這類似於在http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx發現典型的例子其中對數據庫應用構建的字符串:
Dim Northwind as New NorthwindDataContext
Dim query = Northwind.Products _
.Where("CategoryID=2 and UnitPrice>3") _
.OrderBy("SupplierId")
GridView1.Datasource = query
GridView1.Databind()
我缺少什麼?
我終於搞定了。我放棄了原來的方法,因爲截至目前我還不確定它甚至打算用於Xml。我沒有看到任何地方發表反對聲明的觀點。相反,我用喬恩斯基特的迴應this question作爲我的答案的基礎:
XElement e = XElement.Load(new XmlNodeReader(XmlDoc));
List<Func<XElement, bool>> exps = new List<Func<XElement, bool>> { };
exps.Add(GetXmlQueryExprEqual("AGRMNT_TYPE_CODE", "ISDA"));
exps.Add(GetXmlQueryExprNotEqual("WHO_SENDS_CONTRACT_IND", "X"));
List<ConditionalOperatorType> condOps = new List<ConditionalOperatorType> { };
condOps.Add(ConditionalOperatorType.And);
condOps.Add(ConditionalOperatorType.And);
//Hard-coded test value of the select field Id will be resolved programatically in the
//final version, as will the preceding literal constants.
var results = GetValueFromXml(171, e, exps, condOps);
foreach (var x in results)
{
result = x.Value;
break;
}
return result;
...
public static Func<XElement, bool> GetXmlQueryExprEqual(string element, string compare)
{
try
{
Expression<Func<XElement, bool>> expressExp = a => (string)a.Element(element) == compare;
Func<XElement, bool> express = expressExp.Compile();
return express;
}
catch (Exception e)
{
return null;
}
}
public static Func<XElement, bool> GetXmlQueryExprNotEqual(string element, string compare)
{
try
{
Expression<Func<XElement, bool>> expressExp = a => (string)a.Element(element) != compare;
Func<XElement, bool> express = expressExp.Compile();
return express;
}
catch (Exception e)
{
return null;
}
}
private IEnumerable<XElement> GetValueFromXml(int selectFieldId, XElement elem,
List<Func<XElement, bool>> predList, List<ConditionalOperatorType> condOpsList)
{
try
{
string fieldName = DocMast.GetFieldName(selectFieldId);
string xmlPathRoot = DocMast.Fields[true, selectFieldId].XmlPathRoot;
string xmlPathParent = DocMast.Fields[true, selectFieldId].XmlPathParent;
IEnumerable<XElement> results = null;
ConditionalOperatorType condOp = ConditionalOperatorType.None;
switch (predList.Count)
{
case (1):
results =
from r in elem.Elements(xmlPathRoot).Descendants(xmlPathParent)
where (predList[0](r))
select r.Element(fieldName);
break;
case (2):
CondOp = (ConditionalOperatorType)condOpsList[0];
switch (condOp)
{
case (ConditionalOperatorType.And):
results =
from r in elem.Elements(xmlPathRoot).Descendants(xmlPathParent)
where (predList[0](r) && predList[1](r))
select r.Element(fieldName);
break;
case (ConditionalOperatorType.Or):
results =
from r in elem.Elements(xmlPathRoot).Descendants(xmlPathParent)
where (predList[0](r) || predList[1](r))
select r.Element(fieldName);
break;
default:
break;
}
break;
default:
break;
}
return results;
}
catch (Exception e)
{
return null;
}
}
然而這種方法,是從完善顯然遠遠。
- 我有單獨的函數來解析和編譯表達式 - 只是爲了合併不同的條件運算符。更糟糕的是,我將增加更多以支持更多的邏輯運算符和數值;
- GetValueFromXml例程非常笨重,因爲我添加了更多參數,所以必須增加額外的情況。
任何想法或建議將不勝感激。
我以前試過: string where =「Element(\」AGMNT_TYPE_CODE \「)。Value == \」ISDA \「」;並且它會產生一個System.Linq.Dynamic.ParseException: 「XElement類型中不存在可應用的方法'Element' 「」。這似乎是一般的方法應該工作。 (請參閱我上面原文的補充)我確定這只是一個正確的語法問題。在發佈此消息之前,我一再嘗試反覆嘗試和失敗。 –