简体   繁体   中英

C# Selecting XML Elements With XPathSelectElements()

I have this XML, there are multiple Elements of type 'vdsk', I want them all. I only have 1 in here for brevity.

<?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

       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.

Your code is absolutely right and obvious, but MS made decision to be too restrictive related namespaces, what leads to more clumsy code. 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 . 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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