简体   繁体   中英

LINQ query for XML c#

I have simple loop for finding child Element:

XDocument xDoc = XDocument.Load(@"bpmn.xml");
//Run query
foreach (XElement level1Element in xelement.Elements("process"))
{
    System.Diagnostics.Debug.WriteLine(level1Element.Attribute("id").Value);

    foreach (XElement level2Element in level1Element.Elements("task"))
    {
        System.Diagnostics.Debug.WriteLine(
            "  " + level2Element.Attribute("name").Value);
    }
}

Why don't I get any output?

The input XML:

<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:dc="http://www.omg.org/spec/DD/20100524/DC" xmlns:di="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://sourceforge.net/bpmn/definitions/_1384266732154" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:yaoqiang="http://bpmn.sourceforge.net" exporter="Yaoqiang BPMN Editor" exporterVersion="2.2.18 (GPLv3, Non-Commercial)" expressionLanguage="http://www.w3.org/1999/XPath" id="_1384266732154" name="" targetNamespace="http://sourceforge.net/bpmn/definitions/_1384266732154" typeLanguage="http://www.w3.org/2001/XMLSchema" xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL http://bpmn.sourceforge.net/schemas/BPMN20.xsd">   <collaboration id="COLLABORATION_1" isClosed="false">
    <participant id="_2" name="CEO" processRef="PROCESS_1">
      <participantMultiplicity maximum="1" minimum="0"/>
    </participant>
    <participant id="_3" name="Manager" processRef="PROCESS_2">
      <participantMultiplicity maximum="1" minimum="0"/>
    </participant>
    <participant id="_4" name="project Manager" processRef="PROCESS_3">
      <participantMultiplicity maximum="1" minimum="0"/>
    </participant>
    <participant id="_5" name="HR" processRef="PROCESS_4">
      <participantMultiplicity maximum="1" minimum="0"/>
    </participant>
    <participant id="_6" name="Employee" processRef="PROCESS_5">
      <participantMultiplicity maximum="1" minimum="0"/>
    </participant>   </collaboration>   <process id="PROCESS_1" isClosed="false" isExecutable="true" processType="None">
    <startEvent id="_8" isInterrupting="true" name="Start Event" parallelMultiple="false">
      <outgoing>_12</outgoing>
    </startEvent>
    <task completionQuantity="1" id="_9" isForCompensation="false" name="Task" startQuantity="1">
      <incoming>_12</incoming>
      <outgoing>_13</outgoing>
    </task>
    <sendTask completionQuantity="1" id="_10" implementation="##WebService" isForCompensation="false" name="Send Task" startQuantity="1">
      <incoming>_13</incoming>
      <outgoing>_14</outgoing>
    </sendTask>
    <task completionQuantity="1" id="_11" isForCompensation="false" name="Task" startQuantity="1">
      <incoming>_14</incoming>
    </task>
    <sequenceFlow id="_12" sourceRef="_8" targetRef="_9"/>
    <sequenceFlow id="_13" sourceRef="_9" targetRef="_10"/>
    <sequenceFlow id="_14" sourceRef="_10" targetRef="_11"/>   </process>   <process id="PROCESS_2" isClosed="false" isExecutable="true" processType="None">
    <task completionQuantity="1" id="_17" isForCompensation="false" name="Task" startQuantity="1">
      <outgoing>_21</outgoing>
    </task>
    <task completionQuantity="1" id="_19" isForCompensation="false" name="Task" startQuantity="1">
      <incoming>_21</incoming>
      <outgoing>_23</outgoing>
      <outgoing>_25</outgoing>
    </task>
    <sequenceFlow id="_21" sourceRef="_17" targetRef="_19"/>
    <receiveTask completionQuantity="1" id="_22" implementation="##WebService" instantiate="false" isForCompensation="false" name="Receive Task" startQuantity="1">
      <incoming>_23</incoming>
    </receiveTask>
    <sequenceFlow id="_23" name="go on" sourceRef="_19" targetRef="_22"/>
    <task completionQuantity="1" id="_24" isForCompensation="false" name="Task" startQuantity="1">
      <incoming>_25</incoming>
    </task>
    <sequenceFlow id="_25" sourceRef="_19" targetRef="_24"/>   </process> </definitions>

You need to select from the root element. Try changing:

xelement.Elements("process"))

To:

xDoc.Elements("definitions").Elements("process")

Your .xml file provided with namespace, still you should use it in your code. Please try this:

 XDocument xDoc = XDocument.Load(@"xmlfile1.xml");
  //Run query

  XNamespace ns = "http://www.omg.org/spec/BPMN/20100524/MODEL";
  foreach (XElement level1Element in xDoc.Descendants(ns + "process"))
  {
    System.Diagnostics.Debug.WriteLine(level1Element.Attribute("id").Value);

    foreach (XElement level2Element in level1Element.Elements(ns + "task"))
    {
      System.Diagnostics.Debug.WriteLine(
          "  " + level2Element.Attribute("name").Value);
    }
  }

Also, in your case use Descendants() method instead of Elements() . More info http://msdn.microsoft.com/en-us/library/system.xml.linq.xname(v=vs.110).aspx

  1. You need to get the root element first, by xDoc.Root (if xelement in your code is xDoc )
  2. (The main problem here) Your XML has a custom namespace, in which case you need to specify it when calling Elements() .

Putting together:

    XDocument xDoc = XDocument.Load(@"bpmn.xml");
    var ns = XNamespace.Get("http://www.omg.org/spec/BPMN/20100524/MODEL");
    //Run query
    foreach(XElement level1Element in xDoc.Root.Elements(ns + "process"))
    {
        System.Diagnostics.Debug.WriteLine(level1Element.Attribute("id").Value);

        foreach(XElement level2Element in level1Element.Elements(ns + "task"))
        {
            System.Diagnostics.Debug.WriteLine("  " + level2Element.Attribute("name").Value);
        }
    }

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