我需要允许高级用户输入XPath表达式,并向他们显示找到的值或节点或属性。在.Net框架中,可以使用System.Xml.XPath.Extensions来调用XPathEvaluate,但Silverlight没有这个MSDN reference。是否有人重写了在Silverlight中使用的扩展方法?最好的方法是什么?为什么不在Silverlight或工具包中提供(vote on the issue here)?如何评估Silverlight中的XPath表达式?
回答
一种解决方案是使用通用处理程序,并将处理外包给服务器以处理异步请求。这里是一个一步一步:
第一:
在Web项目创建一个通用的处理程序。添加下面的代码的ASHX文件为您的ProcessRequest(简化为简洁):
public void ProcessRequest(HttpContext context)
{
context.Response.ContentType = "text/plain";
string xml = context.Request.Form["xml"].ToString();
string xpath = context.Request.Form["xpath"].ToString();
XmlReader reader = new XmlTextReader(new StringReader(xml));
XDocument doc = XDocument.Load(reader);
var rawResult = doc.XPathEvaluate(xpath);
string result = String.Empty;
foreach (var r in ((IEnumerable<object>)rawResult))
{
result += r.ToString();
}
context.Response.Write(result);
}
应当注意的是,有一些命名空间,你需要的XML处理引用:
System.IO
的System.Xml
System.Xml.XPat^h
System.Xml.Linq的
二:
你需要一些代码,将让你做出一个异步邮寄到通用处理器。下面的代码是漫长的,但本质上你通过以下事项:
您的通用处理器
键值对(假设XML文档中的XPath)
- 的字典的URI
成功和失败的回调
对UserControl的调度计时器的引用,以便您可以在回调中访问您的UI(如有必要)。
下面是一些代码,我放在一个工具类:
public class WebPostHelper
{
public static void GetPostData(Uri targetURI, Dictionary<string, string> dataDictionary, Action<string> onSuccess, Action<string> onError, Dispatcher threadDispatcher)
{
var postData = String.Join("&",
dataDictionary.Keys.Select(k => k + "=" + dataDictionary[k]).ToArray());
WebRequest requ = HttpWebRequest.Create(targetURI);
requ.Method = "POST";
requ.ContentType = "application/x-www-form-urlencoded";
var res = requ.BeginGetRequestStream(new AsyncCallback(
(ar) =>
{
Stream stream = requ.EndGetRequestStream(ar);
StreamWriter writer = new StreamWriter(stream);
writer.Write(postData);
writer.Close();
requ.BeginGetResponse(new AsyncCallback(
(ar2) =>
{
try
{
WebResponse respStream = requ.EndGetResponse(ar2);
Stream stream2 = respStream.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
string responseString = reader2.ReadToEnd();
int spacerIndex = responseString.IndexOf('|') - 1;
string status = responseString.Substring(0, spacerIndex);
string result = responseString.Substring(spacerIndex + 3);
if (status == "success")
{
if (onSuccess != null)
{
threadDispatcher.BeginInvoke(() =>
{
onSuccess(result);
});
}
}
else
{
if (onError != null)
{
threadDispatcher.BeginInvoke(() =>
{
onError(result);
});
}
}
}
catch (Exception ex)
{
string data2 = ex.ToString();
}
}
), null);
}), null);
}
}
三:
请来电转接到您的实用程序类,并通过您的XML和XPath:
private void testButton_Click(object sender, RoutedEventArgs e)
{
Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("xml", "<Foo />");
values.Add("xpath", "/*");
//Uri uri = new Uri("http://eggs/spam.ashx");
Uri uri = new Uri("http://localhost:3230/xPathHandler.ashx");
WebPostHelper.GetPostData(uri, values,
(result) =>
{
MessageBox.Show("Your result " + result);
},
(errMessage) =>
{
MessageBox.Show("An error " + errMessage);
},
this.Dispatcher);
}
让我重申,这里的代码是为简洁起见简化。您可能希望使用序列化程序将更复杂的类型传递给通用处理函数。当您从context.Request.Form集合中获取值时,您需要以防御性方式编写空值守卫“完整性检查”。但基本想法如上所述。
-1。这些天我很少冷静下来,但在这种情况下,我感到有必要这样做。将XML编码为'x-www-form-urlencoded'(带有可能会产生的各种字符编码令人头痛的问题),然后将其全部恢复到服务器上,以执行XPath并返回结果(这也可能很大),据我所知,也会产生难以理解的结果。 – AnthonyWJones 2010-02-25 08:16:36
安东尼,我把你的罕见downvote作为一个“好点”,但我鼓励你提供一个解决方案。 xml文件可能非常大(例如iTunes库),但在许多情况下,它们的设计较小(例如,典型的RSS提要)。带有字符编码的AJAX样式文章(Server.UrlDecode可能应该在示例中)工作正常(取上面的代码并实现它,你将能够看到自己)。 – t3rse 2010-02-25 14:53:00
我认为XPath在Silverlight中不可用的原因是MS希望您使用Linq来代替XML。但这并不完全有助于你。不幸的是,我认为这将很难实现你想要的。如果您必须具备此功能,我认为您将不得不求助于将查询发送到服务器,在那里对其进行评估并返回结果。这是丑陋的,但我认为这是唯一的方法。
我非常怀疑微软__want__你使用Linq。考虑到希望将下载量降到最低,并且Linq非常擅长用XPath处理它未优先处理的事实,它更有可能。 – AnthonyWJones 2010-02-24 19:21:09
事实证明,XPath支持在Silverlight 4中可用: http://programmerpayback.com/2010/04/01/xpath-support-in-silverlight-4-xpathpad/ – 2010-04-06 08:35:49
现在似乎有a NuGet package提供此功能。作者被列为微软。
- 1. 评估Chrome中的xpath表达式
- 2. 如何评估表达式?
- 3. 评估xpath-predicate中的外部xpath表达式
- 4. 如何评估ExpressionVisitor中的表达式?
- 5. 如何评估树中的表达式?
- 6. 如何在AngularJS中评估表达式中的表达式
- 7. 如何使用XPath计数表达式来评估if语句?
- 8. 如何评估另一个表达式中的angularjs表达式
- 9. 在Java中评估XPath表达式的问题
- 10. 是否可以评估xpath表达式中的值?
- 11. 如何评估MathML表达式?
- 12. 如何评估Handlebars表达式?
- 13. Angular如何评估表达式?
- 14. Python如何评估这个表达式?
- 15. 如何评估这些C表达式?
- 16. Python - 如何评估以下表达式?
- 17. 如何评估以下Javascript表达式?
- 18. 在PHP XPath中使用正则表达式 - >评估
- 19. 后缀表达式评估
- 20. JasperReports表达式评估
- 21. Xtext评估表达式
- 22. 内联表达式评估
- 23. Groovy表达式评估
- 24. 无法评估表达式
- 25. 表达式评估序列
- 26. 递归表达式评估?
- 27. 评估数组表达式
- 28. 评估表达式树
- 29. 表达式树评估
- 30. 评估JavaScript表达式
+1我同意我希望看到自己的扩展方法的端口。 – AnthonyWJones 2010-02-24 19:21:40
“高级用户”不是开发者吗?需要支持多大范围的XPath? – AnthonyWJones 2010-02-25 09:03:23
“高级用户”,如某人想要如何使用Xpath而不是我创建的用于帮助他们完成此操作的其余UI。所以他们只需要输入xPath,我会向他们展示结果。 – Aligned 2010-02-25 20:11:09