C#XML查询来自特定父节点的属性,并将它们添加到子节点

时间:2017-11-08 13:38:36

标签: c# xml xml-parsing

所以我有一个xml文件,结构如下:

 <Group Name = "Groceries">
 <Lifetime Creation="2015" Expiration="2018" />
   <Brown Vegetables>
      <Potatoes>
     <LifeTime Creation ="0" Expiration ="0"/>
       </Potatoes>
   </Brown Vegetables>
  <Green Vegetables>
            <Lettuce>
     <LifeTime Creation ="1" Expiration ="1"/>
       </Lettuce>
  <Green Vegetables>
   </Group>

因此,集团名称被视为父母杂货。 我想从包含名称&#34; Groceries&#34;的Group Name中获取LifeTime的属性值, 将它们存储为两个整数,并将两个整数添加到Groupname Groceries下每个孩子的LifeTime

输出:

<Group Name = "Groceries">
 <Lifetime Creation="2015" Expiration="2018" />
   <Brown Vegetables>
      <Potatoes>
     <LifeTime Creation ="2015" Expiration ="2018"/>
       </Potatoes>
   </Brown Vegetables>
  <Green Vegetables>
            <Lettuce>
     <LifeTime Creation ="2016" Expiration ="2019"/>
       </Lettuce>
  <Green Vegetables>
   </Group>

问题在于: 我不知道xml的完整结构,因此可能在Group Name之上有一些其他父节点。我所知道的只是命名空间

我尝试过这样的事情::

 var value = (from c in doc.Descendants("Position") curr.Attribute("X").Value == "");

但我得到的只是空......所以读数不正确

1 个答案:

答案 0 :(得分:0)

我不知道您正在使用的命名空间,因此在下面的代码中按名称获取元素看起来有点乱。所以,让我说清楚,不要只是复制和粘贴这个。使用它显示的逻辑,然后创建自己更整洁的版本。无论如何。下面的代码应该做你想要的

 var groceries = xDoc.Descendants("Group").Where(d => d.Attributes("Name").FirstOrDefault().Value == "Groceries");

        foreach (var grocery in groceries)
        {
            var lifeTimeNode = grocery.Elements().FirstOrDefault(e => e.Name.LocalName == "Lifetime");
            var creationYear = int.Parse(lifeTimeNode.Attribute("Creation").Value);
            var expirationYear = int.Parse(lifeTimeNode.Attribute("Expiration").Value);
            var vegetableLifeTimes = grocery.Elements().Where(e => e.Name.LocalName != "Lifetime").Select(e => e.Descendants().FirstOrDefault(subE => subE.Name.LocalName == "LifeTime"));
            foreach (var vegLifeTime in vegetableLifeTimes)
            {
                var vegCreationModifier = int.Parse(vegLifeTime.Attribute("Creation").Value);
                var vegExpirationModifier = int.Parse(vegLifeTime.Attribute("Expiration").Value);

                var newExpiration = expirationYear + vegExpirationModifier;
                var newCreation = creationYear + vegCreationModifier;

                vegLifeTime.Attribute("Creation").Value = newCreation.ToString();
                vegLifeTime.Attribute("Expiration").Value = newExpiration.ToString();
            }
        }

要记住的一件事是,您发布的XML实际上并不有效,元素名称中有空格,而且我非常确定不会大声说出来。

所以上面的代码适用于这种格式的XML

<Group Name="Groceries">
  <Lifetime Creation="2015" Expiration="2018" />   
  <BrownVegetables>
    <Potatoes>
      <LifeTime Creation ="0" Expiration ="0"/>
    </Potatoes>
  </BrownVegetables>
  <GreenVegetables>
    <Lettuce>
      <LifeTime Creation="1" Expiration="1"/>
    </Lettuce>
    </GreenVegetables>
</Group>