如何连接两个 XML 表并嵌套而不重复
Posted
技术标签:
【中文标题】如何连接两个 XML 表并嵌套而不重复【英文标题】:How to join two XML tables and nest it without repeating 【发布时间】:2021-09-08 07:23:37 【问题描述】:我正在尝试加入下面的两个 XML 文件
XML 文件 1 - 日志
<Journals>
<JournalID>1</JournalID>
<Description>BKI- 1</Description>
</Journals>
<Journals>
<JournalID>2</JournalID>
<Description>BKI- 2</Description>
</Journals>
XML 文件 2 - 事务
<Transaction>
<JID>1</JID>
<TransactionID>0005932053</TransactionID>
<Period>5</Period>
</Transaction>
<Transaction>
<JID>1</JID>
<TransactionID>0005932054</TransactionID>
<Period>8</Period>
</Transaction>
<Transaction>
<JID>2</JID>
<TransactionID>0005932053</TransactionID>
<Period>2</Period>
</Transaction>
<Transaction>
<JID>2</JID>
<TransactionID>0005932053</TransactionID>
<Period>4</Period>
</Transaction>
变成如下图
XML 输出
<Journals>
<JournalID>1</JournalID>
<Description>BKI- 1</Description>
<Transaction>
<JID>1</JID>
<TransactionID>0005932053</TransactionID>
<Period>5</Period>
</Transaction>
<Transaction>
<JID>1</JID>
<TransactionID>0005932054</TransactionID>
<Period>8</Period>
</Transaction>
</Journals>
<Journals>
<JournalID>2</JournalID>
<Description>BKI- 2</Description>
<Transaction>
<JID>2</JID>
<TransactionID>0005932053</TransactionID>
<Period>2</Period>
</Transaction>
<Transaction>
<JID>2</JID>
<TransactionID>0005932053</TransactionID>
<Period>4</Period>
</Transaction>
</Journals>
如您所见,我正在尝试加入它,以便对于每个日记 - 所有交易都将显示为子节点。
到目前为止我的代码 - 未能做到这一点(因为它为每个事务复制 Journals 节点):
XDocument FileTransactions = XDocument.Load("Final_Transaction.xml"); XDocument FileJournals = XDocument.Load("Final_Journals.xml"); var joinQuery = from j in FileJournals.Root.Descendants("Final_Journals") join t in FileTransactions.Root.Descendants("Final_Transaction") on (string)j.Element("JournalID").Value equals (string)t.Element("JID").Value select new XElement("Journals", new XElement("JournalID", (string)j.Element("JournalID")), new XElement("Description", (string)j.Element("Description")), new XElement("Type", (string)j.Element("Type")), new XElement("Transaction", new XElement(t)) );
我需要在这里添加一个 foreach 循环吗?如何在不重复父节点的情况下搭建父节点中的所有相关子节点?
我已经尝试查看教程和其他帖子 - 它们都没有涵盖我面临的复杂性
请指出正确的方向
【问题讨论】:
我会遍历事务文件并将所有单个事务保存到字典中,其中键是JID
,值是事务列表。然后我会遍历日志文件并使用Add
方法注入相应的事务(通过JournalID
)。
【参考方案1】:
您可以使用 for 循环或 join(使用 for 循环)。我用加入。您需要使用格式良好的 xml,因此我在输入中添加了根标签。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.IO;
namespace ConsoleApplication1
class Program
const string journalsStr = @"c:\temp\test.xml";
const string transactionsStr = @"c:\temp\test1.xml";
static void Main(string[] args)
// xml files are not well formed. A well formed xml has only one root tag
string jXml = File.ReadAllText(journalsStr);
jXml = string.Format("<Root>0</Root>", jXml);
XDocument jDoc = XDocument.Parse(jXml);
string tXml = File.ReadAllText(transactionsStr);
tXml = string.Format("<Root>0</Root>", tXml);
XDocument tDoc = XDocument.Parse(tXml);
var query = (from j in jDoc.Descendants("Journals")
join t in tDoc.Descendants("Transaction") on (int)j.Element("JournalID") equals (int)t.Element("JID")
select new j = j, t = t
).ToList();
var groups = query.GroupBy(x => (int)x.j.Element("JournalID")).ToList();
string root = "<Journals></Journals>";
XDocument doc = XDocument.Parse(root);
XElement journals = doc.Root;
foreach (var group in groups)
XElement journal = group.First().j;
foreach (var trans in group)
journal.Add(trans.t);
journals.Add(journal);
【讨论】:
jdweng,非常感谢你——这正是我所需要的。我有点惊讶没有在线教程来解决这类问题......但是你用你的解决方案让我很开心。你是明星!以上是关于如何连接两个 XML 表并嵌套而不重复的主要内容,如果未能解决你的问题,请参考以下文章