C# 当XpathValute可以是XElement或XAttribute时,如何铸造它?
所以我有这个代码:C# 当XpathValute可以是XElement或XAttribute时,如何铸造它?,c#,.net,xml,xpath,C#,.net,Xml,Xpath,所以我有这个代码: List<PriceDetail> prices = (from item in xmlDoc.Descendants(shop.DescendantXName) select new PriceDetail { Price = GetPrice(item.Element(shop.PriceXPath).Value),
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>();
((IEnumerable)item.XPathEvaluate(shop.TitleXPath)).Cast<XAttribute>().First<XAttribute>().Value
价目表=
(来自xmlDoc.substands(shop.substantxname)中的项)
选择新的价格详情
{
Price=GetPrice(item.Element(shop.PriceXPath.Value),
GameVersion=GetGameVersion(((IEnumerable)item.XPathEvaluate(shop.TitleXPath)).Cast().First().Value,item.Element(shop.PlatformXPath.Value),
商店,
Link=item.Element(shop.LinkXPath).Value,
InStock=InStock(item.Element(shop.InStockXPath.Value)
}).ToList();
我遇到的问题是以下代码:
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>();
((IEnumerable)item.XPathEvaluate(shop.TitleXPath)).Cast<XAttribute>().First<XAttribute>().Value
((IEnumerable)item.xpatheevalue(shop.TitleXPath)).Cast().First().Value
有时XPathEvaluate中的对象可能是XElement,然后强制转换不起作用。所以我需要的是一个可以同时使用XAttribute和XElement的演员阵容
有什么建议吗?在进行转换之前,您可以使用如下代码检查类型:
XElement e = item as XElement;
XAttribute a = item as XAttribute;
if(e != null)
//item is of type XElement
else
//item is of type XAttribute
从更改XPath表达式(
shop.TitleXPath
):
someXPathExpression
string(someXPathExpression)
string result = item.XPathEvaluate(shop.TitleXPath) as string;
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);
}
}
至:
someXPathExpression
string(someXPathExpression)
string result = item.XPathEvaluate(shop.TitleXPath) as string;
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);
}
}
然后您可以将代码简化为:
someXPathExpression
string(someXPathExpression)
string result = item.XPathEvaluate(shop.TitleXPath) as string;
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);
}
}
完成工作示例:
someXPathExpression
string(someXPathExpression)
string result = item.XPathEvaluate(shop.TitleXPath) as string;
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);
}
}
XElement
和XAttribute
都是XObject
的形式,因此如果类型XObject
的泛型实例满足您的需要,请将您的Cast
更改为Cast
如果这对您的特定情况不起作用,您可以使用OfType
或OfType
来筛选其中一种,但这需要对输入进行两次传递,一个用于筛选XElement
,第二个用于筛选XAttribute
,如果未找到元素,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;
}
}
公共静态IEnumerable GetXPathValue(此XNode节点,字符串xpath)
{
foreach(在(IEnumerable)节点中的XObject XObject.XPathEvaluate(xpath))
{
如果(xObject是XElement)
收益率返回((XElement)xObject).Value;
else if(xObject是XAttribute)
收益率返回((XAttribute)xObject).Value;
}
}
好的,但我真的不明白如何将其融入我的代码中。你能用我上面的代码做个例子吗?有时项目可能是XElement,然后此代码中的项
只能为XElement。使问题难以理解。对不起,把你弄糊涂了。XPathEvaluate中的对象可能来自XElement,也可能来自依赖于xpath的XAttribute。@Spindel,请参阅更新的答案--现在它包含完整的工作解决方案。@Dimitre,请查看下面我的解决方案。+1。但是如果:else if(xObject是XText){yield return XText.Value;}