根据其他节点的id值创建节点

时间:2013-07-11 20:13:08

标签: c# xml linq

XML文件格式:

    <pl>
     <afs> 
      <af id="1"></af>  
       <af id="2"></af>
     </afs>
     <pss>
      <ps>
       <a>
        <x afid="1"> </x>
        <x afid="2"> </x>
       </a>
      </ps>
      <ps>
        <a>  
         <x afid="2"></x>
        </a>
      </ps>
    </pss>
   </pl>

对于所有afs儿童af节点,我想在父节点中创建具有属性值的节点的子节点。

我使用了以下仅创建空元素的代码。我对比较感到震惊,任何人都可以对此有所了解。这是代码:

if (this.Xml.Descendants("a").Count() > 0) {
      var cs = this.Xml.Descendants("a").ToList();
      var cCounts = containers.Select(i => i.Elements("x").Count());
      var maxCount = containerCounts.Max();
      var afIds = from actionField in this.Xml.Descendants("af").Attributes().ToList(); // Here i get compiler error --                                                         

      foreach (var c in cs)
      {
        int count = c.Elements("x").Count();
    var xList = c.Descendants("x").ToList();
        foreach (var xlst in xList)
    {
         for (int i = count; i < maxCount; i++)
          {
        c.Add(new XElement("x", new XAttribute("afid", "1"))); // instead 1 I should have correct id value
           }
        }
      }
}

我想要的结果是:

  <pl>
         <afs> 
          <af id="1"></af>  
           <af id="2"></af>
         </afs>
         <pss>
          <ps>
           <a>
            <x afid="1"> </x>
            <x afid="2"> </x>
           </a>
          </ps>
          <ps>
            <a> 
             <x afid="1"></x>
             <x afid="2"></x>
            </a>
          </ps>
        </pss>
       </pl>

1 个答案:

答案 0 :(得分:2)

问题是您没有在新元素上设置属性。使用此方法:

public static void ConformDocument(XDocument doc)
{
    var writeElements = doc.Descendants("a").ToList();
    if (writeElements.Count == 0)
        return;

    var root = doc.Descendants("pl");

    var ids = (from afs in root.Descendants("afs")
                from af in afs.Descendants("af")
                from attr in af.Attributes("id")
                select attr.Value).Distinct(StringComparer.Ordinal).ToList();

    var elements = root
        .Descendants("pss")
        .Descendants("ps")
        .Descendants("a")
        .Select(a => new {element = a, aids = a.Descendants("x").Attributes("aid")});

    foreach (var e in elements)
    {
        foreach (var id in ids.Where(id => !e.aids.Any(attr => id.Equals(attr.Value))))
        {
            var element = new XElement("x");
            element.SetAttributeValue("aid", id);
            e.element.Add(element);
        }
    }
}

如果性能成为问题,请告知我,我会为您提供使用XmlReaderXmlWriter的版本。