如何创建一个包含另外 2 个 XML 文件之间的值差异的 XML 文件
How can I create a XML file containing the difference in value between another 2 XML files
你好 C# 爱好者!
我正在尝试根据另外两个 xml 文件的元素减法创建一个 XML 文件(元素值的差异)
例如:
The Source Xml files
寻求输出:
Expected output
我做了一个快速的研究,发现有一个 XML 内容差异的库,但是 none 满足了这个
功能。
我知道这可以通过 System.xml class 解决,但我不知道如何开始。
任何帮助表示赞赏。
XML 文本示例:
<?xml version="1.0" encoding="utf-8"?>
<Report>
<Project>
<Name>P1</Name>
<Runs>10</Runs>
<Errors>5</Errors>
<Successful>5</Successful>
</Project>
.
. Multiple Projects exists here
.
<Project>
<Name>P2</Name>
<Runs>12</Runs>
<Errors>3</Errors>
<Successful>9</Successful>
</Project>
<Timestamp>
<Year>2020</Year>
<Month>6</Month>
<Day>8</Day>
<Hour>12</Hour>
</Timestamp>
</Report>
尝试 xml linq。我假设您在输入和输出文件中都有相同的项目。如果不是,您将需要一个左外部连接。 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication3
{
class Program
{
const string INPUT_FILENAME_1 = @"c:\temp\test.xml";
const string INPUT_FILENAME_2 = @"c:\temp\test1.xml";
const string OUTPUT_FILENAME = @"c:\temp\test.xml2";
static void Main(string[] args)
{
XDocument doc1 = XDocument.Load(INPUT_FILENAME_1);
DateTime date1 = doc1.Descendants("Timestamp")
.Select(x => new DateTime(
(int)x.Element("Year"),
(int)x.Element("Month"),
(int)x.Element("Day"),
(int)x.Element("Hour"),
0, 0)).FirstOrDefault();
XDocument doc2 = XDocument.Load(INPUT_FILENAME_2);
DateTime date2 = doc2.Descendants("Timestamp")
.Select(x => new DateTime(
(int)x.Element("Year"),
(int)x.Element("Month"),
(int)x.Element("Day"),
(int)x.Element("Hour"),
0, 0)).FirstOrDefault();
string ident = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Report></Report>";
XDocument outputDoc = XDocument.Parse(ident);
XElement outputReport = outputDoc.Root;
XElement oldReport;
XElement newReport;
TimeSpan deltaTime;
if (date2 > date1)
{
newReport = doc2.Root;
oldReport = doc1.Root;
deltaTime = date2.Subtract(date1);
}
else
{
newReport = doc1.Root;
oldReport = doc2.Root;
deltaTime = date1.Subtract(date2);
}
var groups = (from n in newReport.Elements("Project")
join o in oldReport.Elements("Project")
on (string)n.Element("Name") equals (string)o.Element("Name")
select new { oldProj = o, newProj = n }
).ToList();
foreach (var group in groups)
{
XElement difference = new XElement("Project", new object[] {
new XElement("Name", (string)group.newProj.Element("Name")),
new XElement("Runs", (int)group.newProj.Element("Runs") - (int)group.oldProj.Element("Runs")),
new XElement("Errors", (int)group.newProj.Element("Errors") - (int)group.oldProj.Element("Errors")),
new XElement("Successful", (int)group.newProj.Element("Successful") - (int)group.oldProj.Element("Successful"))
});
outputReport.Add(difference);
}
XElement newTime = new XElement("Timestamp", new object[] {
new XElement("Year", 0),
new XElement("Month", 0),
new XElement("Day", deltaTime.Days),
new XElement("Hour", deltaTime.Hours)
});
outputReport.Add(newTime);
outputDoc.Save(OUTPUT_FILENAME);
}
}
}
你好 C# 爱好者!
我正在尝试根据另外两个 xml 文件的元素减法创建一个 XML 文件(元素值的差异) 例如:
The Source Xml files
寻求输出:
Expected output
我做了一个快速的研究,发现有一个 XML 内容差异的库,但是 none 满足了这个 功能。
我知道这可以通过 System.xml class 解决,但我不知道如何开始。 任何帮助表示赞赏。
XML 文本示例:
<?xml version="1.0" encoding="utf-8"?>
<Report>
<Project>
<Name>P1</Name>
<Runs>10</Runs>
<Errors>5</Errors>
<Successful>5</Successful>
</Project>
.
. Multiple Projects exists here
.
<Project>
<Name>P2</Name>
<Runs>12</Runs>
<Errors>3</Errors>
<Successful>9</Successful>
</Project>
<Timestamp>
<Year>2020</Year>
<Month>6</Month>
<Day>8</Day>
<Hour>12</Hour>
</Timestamp>
</Report>
尝试 xml linq。我假设您在输入和输出文件中都有相同的项目。如果不是,您将需要一个左外部连接。 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication3
{
class Program
{
const string INPUT_FILENAME_1 = @"c:\temp\test.xml";
const string INPUT_FILENAME_2 = @"c:\temp\test1.xml";
const string OUTPUT_FILENAME = @"c:\temp\test.xml2";
static void Main(string[] args)
{
XDocument doc1 = XDocument.Load(INPUT_FILENAME_1);
DateTime date1 = doc1.Descendants("Timestamp")
.Select(x => new DateTime(
(int)x.Element("Year"),
(int)x.Element("Month"),
(int)x.Element("Day"),
(int)x.Element("Hour"),
0, 0)).FirstOrDefault();
XDocument doc2 = XDocument.Load(INPUT_FILENAME_2);
DateTime date2 = doc2.Descendants("Timestamp")
.Select(x => new DateTime(
(int)x.Element("Year"),
(int)x.Element("Month"),
(int)x.Element("Day"),
(int)x.Element("Hour"),
0, 0)).FirstOrDefault();
string ident = "<?xml version=\"1.0\" encoding=\"utf-8\"?><Report></Report>";
XDocument outputDoc = XDocument.Parse(ident);
XElement outputReport = outputDoc.Root;
XElement oldReport;
XElement newReport;
TimeSpan deltaTime;
if (date2 > date1)
{
newReport = doc2.Root;
oldReport = doc1.Root;
deltaTime = date2.Subtract(date1);
}
else
{
newReport = doc1.Root;
oldReport = doc2.Root;
deltaTime = date1.Subtract(date2);
}
var groups = (from n in newReport.Elements("Project")
join o in oldReport.Elements("Project")
on (string)n.Element("Name") equals (string)o.Element("Name")
select new { oldProj = o, newProj = n }
).ToList();
foreach (var group in groups)
{
XElement difference = new XElement("Project", new object[] {
new XElement("Name", (string)group.newProj.Element("Name")),
new XElement("Runs", (int)group.newProj.Element("Runs") - (int)group.oldProj.Element("Runs")),
new XElement("Errors", (int)group.newProj.Element("Errors") - (int)group.oldProj.Element("Errors")),
new XElement("Successful", (int)group.newProj.Element("Successful") - (int)group.oldProj.Element("Successful"))
});
outputReport.Add(difference);
}
XElement newTime = new XElement("Timestamp", new object[] {
new XElement("Year", 0),
new XElement("Month", 0),
new XElement("Day", deltaTime.Days),
new XElement("Hour", deltaTime.Hours)
});
outputReport.Add(newTime);
outputDoc.Save(OUTPUT_FILENAME);
}
}
}