在兄弟节后代节点的节点的子节点属性值中添加新的子节点

时间:2013-07-16 06:49:30

标签: c# xml linq

以下是xml文档

 <al>
  <hfs>
    <hf id="1">A2</hf> ##1) based these hf nodes  id attributes
    <hf id="2">A1</hf>
  </hfs>
  <psteps>
    <pstep>
      <name>sharepoint</name>
      <lze>
        <lz hid="1">                          ##1) in Lze node need to create same number lz nodes 
                                              ## based previously quoted hf node id attribute        
        <ps>
         <p>
           <text>ziel</text>
           <inhalt>ttt</inhalt>    
         </p> 
          <p>
           <text></text>
           <inhalt></inhalt>
         </p> 
        </ps>
        </lz>
        <lz hid="2">
        <ps>         
         <p>
           <text></text>
           <inhalt></inhalt>                    ##2) lz node with hid = "2" has 2 p nodes
         </p>
         <p>
           <text></text>
           <inhalt></inhalt>
         </p>      
        </ps>
        </lz>
      </lze>
    </pstep>
      <pstep>
      <name>aspnet</name>
      <lze>
        <lz hid="2">                    ## 1)in Lze node need to create same number lz nodes 
                                         ## based previously quoted hf node id attribute 
       <ps>
         <p>
           <text>ziel</text>                 ## 2)lz node with hid = "2" has 1 p node so need 
           <inhalt>ttt</inhalt>              ## node to create 1 more  as previously 
         </p>                                ## lz node
        </ps>
        </lz>      
      </lze>
    </pstep>
  </psteps> 
 </al>

我需要在这里做两件事:

  1. 基于hfs子hf节点我需要在hfs sibling中创建psteps后代lze节点相同数量的具有相同属性值的lz节点

  2. 接下来必须找到具有相同属性值的lz节点中的p个节点的最大数量,并在具有相同属性值的其余lz节点中创建相同数量的p个节点。

  3. 以下是我想要制作的示例xml:

     <al>
      <hfs>
        <hf id="1">A2</hf>
        <hf id="2">A1</hf>
      </hfs>
      <psteps>
        <pstep>
          <name>sharepoint</name>
          <lze>
            <lz hid="1">
            <ps>
             <p>
               <text>ziel</text>
               <inhalt>ttt</inhalt>
             </p> 
              <p>
               <text></text>
               <inhalt></inhalt>
             </p> 
            </ps>
            </lz>
            <lz hid="2">
            <ps>         
              <p>
               <text></text>
               <inhalt></inhalt>
             </p>
             <p>
               <text></text>
               <inhalt></inhalt>
            </p>         
            </ps>
            </lz>
          </lze>
        </pstep>
          <pstep>
          <name>aspnet</name>
          <lze>
            <lz hid="2">
            <ps>
             <p>
               <text>ziel</text>
               <inhalt>ttt</inhalt>
             </p>
             <p>
               <text></text>
               <inhalt></inhalt>
             </p>           
            </ps>
            </lz>      
           <lz hid="1">
            <ps>
             <p>
               <text></text>
               <inhalt></inhalt>
             </p>      
             <p>
               <text></text>
               <inhalt></inhalt>
             </p>          
            </ps>
            </lz>      
          </lze>
        </pstep>
      </psteps> 
     <al>
    

    我使用以下代码来创建缺少的<lz>个节点。我需要创建<p>个节点,我无法从每个<p>节点中选择<lz>个节点。

    var doc = XDocument.Load("XmlFile1.xml");
    var hfIds = (from hf in doc.Descendants("hf")
                    from attr in hf.Attributes("Id")
                    select attr.Value).Distinct(StringComparer.Ordinal).ToList();
    
    var lze2 = doc.Descendants("lze")
            .Select(lze => new {
                element = lze,
                hfids = lze.Descendants("lz").Attributes("hid"),
                paras = (from lz in lze.Elements("lz")
                        from ps in lz.Elements("ps")
                        from p in ps.Elements("p")
                        select p).ToList()
            });
    
    foreach (var c in lze2) {
        foreach (var hfid in hfIds.Where(hfid => !c.hfids.Any(attr => hfid.Equals(attr.Value)))) {
            c.element.Add(new XElement("lz", new XAttribute("hfid", hfid),
                new XElement("ps",
                        new XElement("p"),
                    new XElement("Text"),
                    new XElement("Content"))));
            break;
        }
    }
    
      

    感谢您的帮助

2 个答案:

答案 0 :(得分:0)

这是你想要做的吗?

var doc = XDocument.Load("XmlFile1.xml");
var hfIds = (from hf in doc.Descendants("hf").Attributes("id")
                         select hf.Value).Distinct(StringComparer.Ordinal).ToList();


            bool addFlag = true;

            foreach (var c in doc.Descendants("lze"))
            {
                foreach (var hfid in hfIds)
                {
                    addFlag = true;
                    foreach (var attr in c.Descendants("lz").Attributes("hid"))
                    {
                        if (hfid == attr.Value)
                        {
                            addFlag = false;
                            break;
                        }

                    }
                    if (addFlag)
                    {
                        c.Add(new XElement("lz", new XAttribute("hid", hfid),
                            new XElement("ps",
                                    new XElement("p"),
                                new XElement("Text"),
                                new XElement("Content"))));
                    }
                }
            }


            // Adding the p elements to the above added lz elements
            var distinctPIds = (from hf in doc.Descendants("lz").Descendants("p")
                                select hf).GroupBy(x => x.Value).Select(x => x.First()); ;

            addFlag = true;
            XElement a = null;
            foreach (var c in doc.Descendants("lz").Descendants("ps"))
            {
                foreach (var c3 in distinctPIds)
                {
                    addFlag = true;
                    foreach (var c2 in c.Descendants("p"))
                    {
                        if (XNode.DeepEquals(c2, c3))
                        {
                            addFlag = false;
                            break;
                        }
                        a = c3;
                    }
                    if (addFlag)
                        c.Add(a);
                }
            }
        }

代码可能格式不正确。保持更加口头的理解。

答案 1 :(得分:0)

 if (xmlDoc.Descendants("a").Count() > 0)
   {
     var afIds = (from af in xmlDoc.Descendants("af")
                 from attribute in af.Attributes("Id")
                 select attribute.Value).Distinct(StringComparer.Ordinal).ToList();

     var loContainers = xmlDoc.Descendants("a").Select(a => 
                    new {element = a, afids = a.Descendants("x").Attributes("afId") });

     foreach (var container in loContainers)
     {
       foreach (var afId in afIds.Where(afId => !container.afids.Any(attr => afId.Equals(attr.Value))))
       {
          container.element.Add(new XElement("x", new XAttribute("afId", afId),
                            new XElement("Paragraphs",
                                new XElement("Paragraph",
                                    new XAttribute("AllowSelection", "false"),
                                    new XElement("Text"),
                                    new XElement("Content")))));
             break;
         }
      }

      foreach (var afId in afIds)
      {
        var distinctlearningObjs = from x in xmlDoc.Descendants("x").Where(
                            x => (string)x.Attribute("afId").Value == afId).GroupBy(
                                x => x.Attribute("afId").Value)
                      select new { MaxParaCount = x.Max(y => y.Descendants("Paragraph").Count ()) };

         foreach (var x in distinctlearningObjs)
         {
            var docLos = from doclo in xmlDoc.Descendants("x").Where(
                                x => (string)x.Attribute("afId").Value == afId)
                        select new { doclo,  element = doclo.Element("Paragraphs"),
                                    count = doclo.Descendants("Paragraph").Count()
                        };

             foreach (var docLo in docLos)
             {
                var paraCount = docLo.count;
                var maxCount = x.MaxParaCount;

                for (var i = paraCount; i < maxCount; i++)
                {
                   docLo.element.Add(new XElement("Paragraph",
                                    new XAttribute("AllowSelection", "false"),
                                    new XElement("Text"),
                                    new XElement("Content")));
                 }
              }
           }
         }
      }