简体   繁体   English

C# 使用 XPathSelectElements() 选择 XML 元素

[英]C# Selecting XML Elements With XPathSelectElements()

I have this XML, there are multiple Elements of type 'vdsk', I want them all.我有这个 XML,有多个“vdsk”类型的元素,我想要它们。 I only have 1 in here for brevity.为简洁起见,我这里只有 1 个。

<?xml version="1.0" encoding="utf-8" ?>
<diskStatsColl
xmlns="http://ibm.com/storage/management/performance/api/2005/08/vDiskStats"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://ibm.com/storage/management/performance/api/2005    /08/vDiskStats schema/SVCPerfStatsV.xsd" scope="node" id="node1" cluster="v7000nd01"    node_id="0x0000000000000001" cluster_id="0x00000200a0421666" sizeUnits="512B" timeUnits="msec" contains="virtualDiskStats" timestamp="2013-04-30 07:04:13" timezone="GMT-6:00">
<vdsk idx="0"
ctr="137111307" ctrs="3553815134" ctw="580314768"
ctws="12467258075" ctp="107973069" ctps="6910276416"
ctrh="91819453" ctrhs="2398189867" ctrhp="67411787"/>

<vdsk idx="1"
ctr="137111307" ctrs="3553815134" ctw="580314768"
 ctws="12467258075" ctp="107973069" ctps="6910276416"
ctrh="91819453" ctrhs="2398189867" ctrhp="67411787"/>
</diskStatsColl>

I can get the attributes of the root element.我可以获得根元素的属性。 I can't seem to get any of the child elements of the root.我似乎无法获得根的任何子元素。
This code works, but is messy and a kludge此代码有效,但混乱且混乱

  List<XElement> allels = ioxdoc.Elements().ToList();
  List<XElement> allelselements = allels[0].Elements().ToList();                 
  var vdisks = from vdisk in allelselements.
    Where(a => a.Name.ToString().Contains("vdsk"))    
       select vdisk;

I am trying to get it to work with XPathSelectElements(), I have tried these based on examples and examples I found here but the list is always empty我试图让它与 XPathSelectElements() 一起工作,我已经根据我在此处找到的示例和示例尝试了这些,但列表始终为空

       List<XElement> allels = ioxdoc.Root.XPathSelectElements("vdsk").ToList();
       allels = ioxdoc.XPathSelectElements("xml/root/vdsk").ToList();
        allels = ioxdoc.XPathSelectElements("/root/vdsk").ToList();

Why don't you do this:你为什么不这样做:

var allels = ioxdoc.Root.Descendants().ToList();

The above line correctly reports 2 <vdsk> s.上面的行正确报告了 2 <vdsk> s。

Your code is absolutely right and obvious, but MS made decision to be too restrictive related namespaces, what leads to more clumsy code.您的代码绝对正确且显而易见,但 MS 决定对相关命名空间过于严格,导致代码更加笨拙。 Say, if your root element has default namespace:假设您的根元素具有默认命名空间:

<diskStatsColl xmlns="default, unnecessary namespace">
    <vdsk ...>

Then you cannot simply select "vdsk" - you MUST include namespace manager in every single call to XPathSelectElements .那么您不能简单地选择“vdsk”——您必须在每次调用XPathSelectElements都包含名称空间管理器。 Final code will be like this:最终代码将是这样的:

var xml = XDocument.Load("your file");
var ns = new XmlNamespaceManager(new NameTable());
ns.AddNamespace("foo", "default, unnecessary namespace");
var coll = xml.XPathSelectElements("//foo:node", ns).ToList();
var otherColl = xml.XPathSelectElements("/foo:diskStatsColl/foo:node", ns).ToList();

Verbose, ugly code, but you cannot avoid it.冗长、丑陋的代码,但你无法避免。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM