Spi*_*del 10 .net c# xml xpath
所以我有这个代码:
List<PriceDetail> prices =
(from item in xmlDoc.Descendants(shop.DescendantXName)
select new PriceDetail
{
Price = GetPrice(item.Element(shop.PriceXPath).Value),
GameVersion = GetGameVersion(((IEnumerable)item.XPathEvaluate(shop.TitleXPath)).Cast<XAttribute>().First<XAttribute>().Value, item.Element(shop.PlatformXPath).Value),
Shop = shop,
Link = item.Element(shop.LinkXPath).Value,
InStock = InStock(item.Element(shop.InStockXPath).Value)
}).ToList<PriceDetail>();
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是这段代码:
((IEnumerable)item.XPathEvaluate(shop.TitleXPath)).Cast<XAttribute>().First<XAttribute>().Value
Run Code Online (Sandbox Code Playgroud)
有时来自XPathEvaluate的对象可能是XElement,然后转换不起作用.所以我需要的是一个适用于XAttribute和XElement的Cast.
有什么建议吗?
Dim*_*hev 14
shop.TitleXPath从以下位置更改XPath表达式():
someXPathExpression
Run Code Online (Sandbox Code Playgroud)
到:
string(someXPathExpression)
Run Code Online (Sandbox Code Playgroud)
然后你可以简化代码:
string result = item.XPathEvaluate(shop.TitleXPath) as string;
Run Code Online (Sandbox Code Playgroud)
完整的工作示例:
using System;
using System.IO;
using System.Xml.Linq;
using System.Xml.XPath;
class TestXPath
{
static void Main(string[] args)
{
string xml1 =
@"<t>
<a b='attribute value'/>
<c>
<b>element value</b>
</c>
<e b='attribute value'/>
</t>";
string xml2 =
@"<t>
<c>
<b>element value</b>
</c>
<e b='attribute value'/>
</t>";
TextReader sr = new StringReader(xml1);
XDocument xdoc = XDocument.Load(sr, LoadOptions.None);
string result1 = xdoc.XPathEvaluate("string(/*/*/@b | /*/*/b)") as string;
TextReader sr2 = new StringReader(xml2);
XDocument xdoc2 = XDocument.Load(sr2, LoadOptions.None);
string result2 = xdoc2.XPathEvaluate("string(/*/*/@b | /*/*/b)") as string;
Console.WriteLine(result1);
Console.WriteLine(result2);
}
}
Run Code Online (Sandbox Code Playgroud)
执行此程序时,相同的XPath表达式应用于两个不同的XML文档,并且无论string()第一次参数是属性还是第二次的元素,我们都会得到正确的结果 - 写入控制台:
attribute value
element value
Run Code Online (Sandbox Code Playgroud)
如果找不到元素,Dimitre 的解决方案将返回空字符串;我们无法将它与实际的空值区分开来。所以我不得不制作这个扩展方法,通过 XPath 查询处理多个结果,如果没有找到,则返回空枚举:
public static IEnumerable<string> GetXPathValues(this XNode node, string xpath)
{
foreach (XObject xObject in (IEnumerable)node.XPathEvaluate(xpath))
{
if (xObject is XElement)
yield return ((XElement)xObject).Value;
else if (xObject is XAttribute)
yield return ((XAttribute)xObject).Value;
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
XElement并且XAttribute都是形式XObject,因此如果类型的通用实例XObject足以满足您的需要,请将Cast转换<XAttribute>为Cast <XObject>.
如果这不适用于您的特定情况,您可以使用OfType <XAttribute>或OfType <XElement>来过滤其中一个,但这需要两次通过输入,一个用于过滤,XElement第二个用于过滤XAttribute.