我有xml文件,如下所示。
<Root>
<Main Name="Install">
<Details>Success</Details>
<Maintain>Install period</Maintain>
</Main>
<Main Name="Uninstall">
<Details>failure</Details>
<Maintain>uninstall period</Maintain>
</Main>
<Main Name="Discard">
<Details>failure</Details>
<Maintain>discard period</Maintain>
</Main>
<Main Name="Install">
<Details>Done</Details>
<Maintain>Got Output</Maintain>
</Main>
</Root>
我只需要最后一次更新即可在xml中打印。
我使用了以下代码并找到了输出。
XDocument xDoc1 = XDocument.Load(inputFileName);
var elems = xDoc1.Element("Root").Elements("Main");
XElement xInstall = elems.LastOrDefault(a => a.Attribute("Name").Value == "Install");
XElement xUninstall = elems.LastOrDefault(a => a.Attribute("Name").Value == "Uninstall");
XElement xDiscard = elems.LastOrDefault(a => a.Attribute("Name").Value == "Discard");
XDocument xdoc2 = new XDocument();
xdoc2.Add(
new XElement("Root", new XElement[]
{
xInstall,
xDiscard,
xUninstall
})
);
xdoc2.Save(ouputFileName);
但是在foreach循环中使用相同的逻辑时,我无法获得正确的输出。我的代码是,
XmlDocument xml = new XmlDocument();
string xmlLocation = @"C:\Input.xml";
xml.Load(xmlLocation);
XmlNodeList MainNameList = xml.SelectNodes("/Root/Main");
XDocument xDoc1 = XDocument.Load(@"C:\Input.xml");
var elems = xDoc1.Element("Root").Elements("Main");
XDocument xdoc2 = new XDocument();
xdoc2.Add(new XElement("Root"));
foreach (XmlNode MainNode in MainNameList)
{
string mainName = MainNode.Attributes[0].Value;
XElement MainNode = elems.LastOrDefault(a => a.Attribute("Name").Value == mainName);
xdoc2.Root.Add(new XElement("Root", new XElement(MainNode)));
}
xdoc2.Save(@"C:\Output.xml");
输出结果如下:
<Root>
<Main Name="Install">
<Details>Success</Details>
<Maintain>Naveen</Maintain>
</Main>
<Main Name="Uninstall">
<Details>failure</Details>
<Maintain>uninstall period</Maintain>
</Main>
<Main Name="Discard">
<Details>failure</Details>
<Maintain>discard period</Maintain>
</Main>
<Main Name="Install">
<Details>Success</Details>
<Maintain>Naveen</Maintain>
</Main>
</Root>
但我需要输出如下:
<Root>
<Main Name="Uninstall">
<Details>failure</Details>
<Maintain>uninstall period</Maintain>
</Main>
<Main Name="Discard">
<Details>failure</Details>
<Maintain>discard period</Maintain>
</Main>
<Main Name="Install">
<Details>Done</Details>
<Maintain>Got Output</Maintain>
</Main>
</Root>
我的代码有什么错误?请帮助我使用foreach循环获得正确的输出。因为我的xml中有很多主要元素。提前谢谢。
答案 0 :(得分:0)
如果xml中存在任何重复节点(具有重复的属性名称),则以下代码段将忽略所有副本并选择最后一个元素。
XmlDocument xml = new XmlDocument();
string xmlLocationInput = @"C:\Users\jprabadiya\Desktop\Input.xml";
string xmlLocationOutput = @"C:\Users\jprabadiya\Desktop\Output.xml";
xml.Load(xmlLocationInput);
XDocument xDoc1 = XDocument.Load(xmlLocationInput);
var elems = xDoc1.Element("Root").Elements("Main");
var nodeList = elems.GroupBy(d => d.Attribute("Name").Value).Select(d => d.Last()).ToList();
XDocument xdoc2 = new XDocument();
xdoc2.Add(new XElement("Root"));
xdoc2.Root.Add(nodeList);
xdoc2.Save(xmlLocationOutput);
输出:
<?xml version="1.0" encoding="utf-8"?>
<Root>
<Main Name="Install">
<Details>Done</Details>
<Maintain>Got Output</Maintain>
</Main>
<Main Name="Uninstall">
<Details>failure</Details>
<Maintain>uninstall period</Maintain>
</Main>
<Main Name="Discard">
<Details>failure</Details>
<Maintain>discard period</Maintain>
</Main>
</Root>
答案 1 :(得分:0)
您正在使用两个不同的XML库,我将其简化为Linq2XML。
XDocument xDoc1 = XDocument.Load(@"C:\Input.xml");
var elems = xDoc1.Descendants("Main");
// Get all the main names in the input file (1 of each)
string[] names = elems
.Select(main => main.Attribute("Name").Value)
.Distinct()
.ToArray();
XDocument xdoc2 = new XDocument();
XElement root;
xdoc2.Add(root = new XElement("Root"));
foreach (string name in names)
{
XElement node = elems
.LastOrDefault(a => a.Attribute("Name").Value == name);
root.Add(new XElement(node));
}
xdoc2.Save(@"C:\Output.xml");
答案 2 :(得分:0)
原因是每次找到名为“X”的元素时,只需输出名称为“X”的最后一个元素。但是,你不记得你是否已经过了它。
您只需使用List<string>
并记住您输出的项目即可。
同时,通过确定LINQ,对项目进行分组并从每个组中提取最后一个项目,可以轻松实现此结果:
XDocument xDoc1 = XDocument.Load(@"C:\Input.xml");
var elemsNew = xDoc1.Element("Root").Elements("Main")
.GroupBy(x => x.Attribute("Name").Value)
.Select(g => g.Last())
.ToArray();
XDocument xDoc2 = new XDocument(new XElement("Root", elemsNew));
xDoc2.Save(@"C:\Output.xml");