如何过滤XDocument的结果?

时间:2014-11-26 14:25:11

标签: c# asp.net linq

我通过网络服务获取有关学校的一些数据。返回XML看起来像这样:

<document>
  <orgType>
   <orgParent>
      <parentID>21</parentID>
      <parentName>My School</parentName>
      <unit>
        <unitID>2</unitID>
        <unitName>Logistics</unitName>
        <childUnit>
          <childUnitName></childUnitName>
          <opB>
            <Program>601</Program>
            <ProgramName>Short</ProgramName>
            <Method>903001</Method>
            <Type>915001</Type>
          </opB>
        </childUnit>
      </unit>
      <unit>
        <unitID>3</unitID>
        <unitName>Trading</unitName>
        <childUnit>
          <childUnitName></childUnitName>
          <opB>
            <Program>731</Program>
            <ProgramName>Short</ProgramName>
            <Method>903001</Method>
            <Type>915001</Type>
          </opB>
        </childUnit>
      </unit>
      <unit>
        <unitID>4</unitID>
        <unitName>Food Control and Quality Analysis</unitName>
        <childUnit>
          <childUnitName></childUnitName>
          <opB>
            <Program>734</Program>
            <ProgramName>Short</ProgramName>
            <Method>903001</Method>
            <Type>915001</Type>
          </opB>
        </childUnit>
      </unit>
    </orgParent>
     <orgParent>
      <parentID>16</parentID>
      <parentName>Her School</parentName>
      <unit>
        <unitID>1</unitID>
        <unitName>Poultry</unitName>
        <childUnit>
          <childUnitName></childUnitName>
          <opB>
            <Program>573</Program>
            <ProgramName>Short</ProgramName>
            <Method>903001</Method>
            <Type>915001</Type>
          </opB>
        </childUnit>
      </unit>
      <unit>
        <unitID>27</unitID>
        <unitName>Forestry</unitName>
        <childUnit>
          <childUnitName></childUnitName>
          <opB>
            <Program>856</Program>
            <ProgramName>Short</ProgramName>
            <Method>903001</Method>
            <Type>915001</Type>
          </opB>
        </childUnit>
      </unit>
    </orgParent>
  </orgType>
</document>

我可以将parentID和parentName值转换为单独的List对象。

    XDocument xdoc = new XDocument();

    List<string> parentUnitNames = getParentUnitNames();
    List<string> parentUnitIDs = getParentUnitIDs();

    int i = 0;
    foreach (string parentUnitName in parentUnitNames)
    {
         contentDiv.InnerHtml += String.Format("<h2>{0}</h2>", parentUnitName);

        List<string> unitNames = getUnitNames(parentUnitID[i]);
        List<string> unitIDs = getUnitIDs(parentUnitID[i]);

        foreach (string unitName in unitNames)
        {
            contentDiv.InnerHtml += String.Format("<h4>{0}</h4>", unitName);
        }
        i++;
    }

问题是所有学校的所有学校都列在所有学校。换句话说,如果第一所学校有三个部门,第二所学校有两个部门,那么第一所学校的部门名单有5个项目,第二个学校的部门名单也有5个项目。

根据上面的代码页面有这样的视图

<h2>My School</h2>
    <h4>Logistics</h4>
    <h4>Trading</h4>
    <h4>Food Control and Quality Analysis</h4>
    <h4>Poutry</h4>
    <h4>Forestry</h4>
<h2>Her School</h2>
    <h4>Logistics</h4>
    <h4>Trading</h4>
    <h4>Food Control and Quality Analysis</h4>
    <h4>Poutry</h4>
    <h4>Forestry</h4>

应该是

<h2>My School</h2>
    <h4>Logistics</h4>
    <h4>Trading</h4>
    <h4>Food Control and Quality Analysis</h4>
<h2>Her School</h2>
    <h4>Poutry</h4>
    <h4>Forestry</h4>

我应该写一个Where&lt;&gt;限制者专注于每个学校的学校自己的节点,但不知道如何和什么。

我的方法如下:

protected List<string> getParentUnitIDs()
{
    List<string> myList = new List<string>();

    var parentUnitIDs = XDocument.Parse(service.getOrganizationTree())
                                  .Descendants("parentID")
                                  .Select(x => x.Value);


    foreach (string s in parentUnitIDs)
    {
        myList.Add(s);
    }
    return myList;
}


protected List<string> getUnitIDs(string parentUnitID)
{
    List<string> myList = new List<string>();

    var unitIDs = XDocument.Parse(service.getOrganizationTree())
                               .Descendants("unitID")
                               .Select(x => x.Value)
                              //Where() condition should be here I guess

    foreach (string s in unitIDs )
    {
        myList.Add(s);
    }
    return myList;
}

3 个答案:

答案 0 :(得分:1)

试试这个: -

var result = xdoc.Root.Descendants("orgParent")
                      .Where(x => x.Element("parentName").Value == "My School")
                      .Descendants("unit")
                      .Select(x => x.Element("unitName").Value).ToList();

这里我将parentName硬编码为“我的学校”,您可以替换为传递给自定义函数的值。另外,替换我与您xdoc使用的XDocument.Parse(service.getOrganizationTree())变量,因为我在本地编译了此代码。

答案 1 :(得分:1)

如果你尝试并在同样的扫描中做到这一点怎么办?像

contentDiv.InnerHtml = "";
XDocument doc = XDocument.Parse(xml);

var parents = doc.XPathSelectElements("//orgParent");
foreach (XElement parent in parents)
{
    contentDiv.InnerHtml += string.Format("<h2>{0}</h2>", parent.Value);
    var units = parent.XPathSelectElements("//unit");
    foreach (XElement unit in units)
    {
        contentDiv.InnerHtml += string.Format("<h4>{0}</h4>", unit.Value);
    }
}

致以最诚挚的问候,

zerratar。

答案 2 :(得分:0)

我会从对象的角度来看待它而不是尝试使用XML。

将XML转换为对象模型,然后使用对象模型。

class OrgParent
{
  int ID {get;set;}
  string Name {get;set;}
  List<Unit> Units {get; set;}
}

class Unit
{ 
   int ID {get;set;}
  string Name {get;set;}
}

..意味着您的代码变为:

XDocument xdoc = new XDocument();

List<OrgParent> parents = GetParents(); //Transforms all XML into object model

foreach (var parent in parents)
{
    contentDiv.InnerHtml += String.Format("<h2>{0}</h2>", parent.Name);

    foreach (var unit in parent.Units)
    {
        contentDiv.InnerHtml += String.Format("<h4>{0}</h4>", unit.Name);
    }
}