Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当XpathValute可以是XElement或XAttribute时,如何铸造它?_C#_.net_Xml_Xpath - Fatal编程技术网

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;}