Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果子节点元素相等,如何添加父节点?_C#_.net_Xml_Linq_Linq To Xml - Fatal编程技术网

C# 如果子节点元素相等,如何添加父节点?

C# 如果子节点元素相等,如何添加父节点?,c#,.net,xml,linq,linq-to-xml,C#,.net,Xml,Linq,Linq To Xml,我有一组非常大的xml数据。因此在“SECTION”中包含“Piece”节点,它们对于“SECTION name=“RF1WB-1”,SECTION name=“RF1WB-2”,SECTION name=“RF1WB-3”节点具有相同的值。因此,如果“Piece>,我想添加“Parent”,作为它们的父节点“标记包含与第二个XML中所示相同的值 如果子节点元素包含相同的值,如何添加父节点 XmlDocument doc = new XmlDocument(); doc.Load("..\\MF

我有一组非常大的xml数据。因此在
“SECTION”
中包含
“Piece”
节点,它们对于
“SECTION name=“RF1WB-1”
SECTION name=“RF1WB-2”
SECTION name=“RF1WB-3”
节点具有相同的值。因此,如果
“Piece>,我想添加
“Parent”
,作为它们的父节点“
标记包含与第二个XML中所示相同的值

如果子节点元素包含相同的值,如何添加父节点

XmlDocument doc = new XmlDocument();
doc.Load("..\\MFAB1.xml");        
XmlNodeList xnList = doc.SelectNodes("MFAB.ini/SECTION");
foreach (XmlNode xn in xnList)
{
    if (xn.HasChildNodes)
    {
        foreach (XmlNode item in xn.SelectNodes("Piece"))
        {
            if (xn.ChildNodes[0].InnerText.ToString().Contains(s3))
            {
                d1.Piece = xn.ChildNodes[0].InnerText.ToString();
            }
            ______________
            ______________
            ______________
        }
    }
}

输入文件:

<?xml version="1.0" encoding="UTF-8"?>
<MFAB.ini>
 <SECTION name="RF1WB-1">
    <Piece>
      RF1-1
    </Piece>
</SECTION>
  <SECTION name="RF1WB-2">
    <Piece>
      RF1-1
    </Piece>
</SECTION>
  <SECTION name="RF1WB-3">
    <Piece>
      RF1-1
    </Piece>
  </SECTION>
  <SECTION name="RF1-2WB-1">
    <Piece>
      RF1-2
    </Piece>
 </SECTION>
  <SECTION name="RF1-2WB-2">
    <Piece>
      RF1-2
    </Piece>
 </SECTION>
</MFAB.ini>

RF1-1
RF1-1
RF1-1
RF1-2
RF1-2

预期输出文件:

<?xml version="1.0" encoding="UTF-8"?>
<MFAB.ini>
 <SECTION name="RF1WB-1">
    <Piece>
      RF1-1
    </Piece>
</SECTION>
  <SECTION name="RF1WB-2">
    <Piece>
      RF1-1
    </Piece>
</SECTION>
  <SECTION name="RF1WB-3">
    <Piece>
      RF1-1
    </Piece>
  </SECTION>
  <SECTION name="RF1-2WB-1">
    <Piece>
      RF1-2
    </Piece>
 </SECTION>
  <SECTION name="RF1-2WB-2">
    <Piece>
      RF1-2
    </Piece>
 </SECTION>
</MFAB.ini>
我需要的是:

<?xml version="1.0" encoding="UTF-8"?>
<MFAB.ini>
<Parent name = "RF1-1">
 <SECTION name="RF1-1WB-1">
    <Piece>
      RF1-1
    </Piece>
</SECTION>
  <SECTION name="RF1-1WB-2">
    <Piece>
      RF1-1
    </Piece>
</SECTION>
  <SECTION name="RF1-1WB-3">
    <Piece>
      RF1-1
    </Piece>
  </SECTION>
</Parent>
<Parent name = "RF1-2">
  <SECTION name="RF1-2WB-1">
    <Piece>
      RF1-2
    </Piece>
 </SECTION>
  <SECTION name="RF1-2WB-2">
    <Piece>
      RF1-2
    </Piece>
 </SECTION>
</Parent>
</MFAB.ini>

RF1-1
RF1-1
RF1-1
RF1-2
RF1-2

您可以通过
标记对元素进行分组,然后将它们作为
标记的子元素,方法如下:

var xml = XDocument.Load(@"input file");

var result = new XElement(xml.Root.Name, xml.Root.Attributes().ToArray(),
    xml.Root.Elements().GroupBy(x => x.Element("Piece").Value.Trim()).Select(x =>
        new XElement("Parent", new XAttribute("name", x.Key), x))
    );

result.Save(@"output file");

为了方便您自己,您可以使用
XmlSerializer
来读取数据,并且可以像这样为Xml定义dto

[XmlRoot("MFAB.ini")]
public class Mfab {
    [XmlElement("SECTION")]
    public Section[] Sections { get; set; }
}

public class Section {
    [XmlAttribute("name")]
    public string Name { get; set; }
    [XmlElement("Piece")]
    [XmlText]
    public string Piece { get; set; }
}
这将按原样阅读您的文档,将所有部分作为Mfab类的一部分(对不起,我不知道这些类的更好名称;)

这个Xml,你可以这样读

private static T GetXmlFromFile<T>(string filename) {
    XmlSerializer xs = new XmlSerializer(typeof(T));
    using (var fs = new FileStream(filename, FileMode.Open, FileAccess.Read))
    {
        return (T)xs.Deserialize(fs);
    }
}
private static void SaveToXml(object data, string filename) {
    XmlSerializer xs = new XmlSerializer(data.GetType());
    using (var fs = new FileStream(filename, FileMode.Create, FileAccess.Write)) {
        xs.Serialize(fs, data);
    }
}
ParentSection
仍然重用以前创建的

现在要进行转换,我们可以实现以下步骤

// get the xml from a file
var source = GetXmlFromFile<Mfab>(Path.Combine(Environment.CurrentDirectory, "data.xml"));
// group all the sections by it's Piece
var groupedSections = source.Sections.GroupBy(section => section.Piece);
// convert the sections from the Grouped section to a parent section with name as attribute
var parentSections = groupedSections.Select(grp => new ParentSection
{
    Name = grp.Key,
    Sections = grp.ToArray()
}).ToArray();
// save the xml to a new file (which could now be read with the MfabWithParents class)
SaveToXml(new MfabWithParents { Parents = parentSections }, Path.Combine(Environment.CurrentDirectory, "data2.xml"));

那么您希望根据自己的算法对数据进行分组?是的。林克也试过了,但运气不好。根据“工件”节点元素的不同,需要向其添加父元素。是的,为它们定义了类。我也得到了所有的数据和元素。只需要为它添加“Parent”标记。谢谢。你把它们一块一块地分组了吗?您有定义xml的类吗?是的,我现在更新了它们。在“x.Element(“Piece”).Value.Trim()处引发空引用异常使用您的输入文件进行精确测试并正常工作。如果抛出空引用异常,则表示您正在测试的文件与您与我们共享的文件不同,例如,有一个元素没有
Piece
标记或标记值为空。@MadhuKumar只需添加
x.element(“Piece”)?.value?.trim()
就足够了;)@Icepickle从技术上讲这已经足够了,但这意味着文件有一些问题,不能按
片段进行分组。如果是,或者这意味着他的规范不够具体:)无论如何,这将允许他作为额外的父级处理空值:)确定它仍然可以分组,只有父级的name属性将为null