有没有办法管理不规则XML文档的更改,就像使用DataTable一样?

我正在寻找一种方法来导入和导出XML数据文档的更改列表(不规则的结构;不自然地适合DataSet)。

如果我有一个常规结构,我将使用DataTable,我可以评估哪些记录已被编辑,然后提交或取消更改,我还可以传输所需更改的数据包。

如何使用XML数据执行此操作?

如果没有一个好的答案我认为我最好的选择是使用DataTable和方案[XPath,Value],尽管存储效率低,导航困难。

我希望对文档进行更改(使用XPath或LINQ或数据绑定控件或其他),然后记住更改并仅通过TCP发送更改。

然后我想收到另一个更改列表并将其应用于XML文档。 我不想发送整个文档的大小,因为我需要知道并评估发送的更改。

(只是为了澄清:我的程序需要发送和接收文档更改。管道的另一端不是基于.net,并不是这个问题的一部分。)

您是否需要对此更改进行操作或仅存储它们,如果您只想存储更新的版本,则可以使用二进制diff算法来传递2 xml文件之间的差异。 然后以不同的方式更新存储的版本。 对此的好算法是bifdiff C#版本可以在这里找到。

另一个方法是使用MS的这个XmlDiff类

  1. 你怎么想只发送变化?
  2. 您是否期望每次都有大量的变化或只是轻微的变化?
  3. 你需要考虑什么样的变化?
  4. 您是否尝试跨进程边界维护同一文档的副本?
  5. 你如何解决相互冲突的变化?
  6. 您是否要在更改传播之前锁定xml文档?
  7. 两个副本是独立的,还是一个是主副本?

如果您使用了NodeInserted,NodeDeleted,NodeChanged等XmlDocument事件,则可以构建此类更改的列表,然后在另一个副本上执行它们。 如果更改总量超过文档本身,则可以发送文档。 压缩xml数据也有帮助。

除此之外,我没有看到任何其他简单的方法。

当您获得具有不规则结构的XML数据时; 不自然地拟合DataSet,并且您希望对象模型轻松处理数据。 您可以将XML架构定义工具(Xsd.exe)与/ classes选项一起使用,以从XML文件生成C#或VB.Net类。

XSD.exe位于:

C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\xsd.exe C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\xsd.exe 

您从Visual Studio命令行运行xsd.exe。
-开始
– 所有程序
-视觉工作室
-Tools
-命令行

这是查看所有XSD命令行参数的命令:

 xsd /? 

要将不规则的XML文件(XmlResponseObject.xml)转换为Classes:

 xsd c:\Temp\XmlResponseObject.xml /classes /language:CS /out:c:\Temp\ 

这将生成一个包含表示XML的类的csharp文件。 您可能希望将其重新输入到单独的类文件中,注意单个文件中的副本类,这些类通过命名空间消除歧义。 无论哪种方式,类都不是最好看的所有xml属性,但好的部分是你可以通过XML绑定它们。 这是我通过REST Web服务检索XML的示例,xmlResponseObject是适合XML的类的ObjectModel。

 public interface IYourWebService { XmlResponseObject GetData(int dataId); } public class YourWebService : IYourWebService { public XmlResponseObject GetData(int dataId) { XmlResponseObject xmlResponseObject = null; var url = "http://SomeSite.com/Service/GetData/" + dataId; try { var request = WebRequest.Create(url) as HttpWebRequest; if (request != null) { request.AllowAutoRedirect = true; request.KeepAlive = true; request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; .NET CLR 2.0.50727; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729; .NET CLR 1.1.4322; InfoPath.2; .NET4.0C; .NET4.0E)"; request.Credentials = CredentialCache.DefaultNetworkCredentials; request.CookieContainer = new CookieContainer(); var response = request.GetResponse() as HttpWebResponse; if (request.HaveResponse && response != null) { var streamReader = new StreamReader(response.GetResponseStream()); var xmlSerializer = new XmlSerializer(typeof(XmlResponseObject)); xmlResponseObject = (XmlResponseObject)xmlSerializer.Deserialize(streamReader); } } } catch (Exception ex) { string debugInfo = "\nURL: " + url; Console.Write(ex.Message + " " + debugInfo + " " + ex.StackTrace); } return xmlResponseObject; } } 

鉴于您希望仅发送和接收文档更改,您可以使用IsDirty标志修改类。 我敢肯定,一旦你有了可以使用的课程,就很容易检测出差异。

要将任何XML数据加载到DataSet ,您必须提供相应的模式。
请参阅从XML架构(XSD)派生DataSet关系结构 。

此外, DataSet / DataTable不适用于XML文档。 他们可以从中导入数据,并将数据导出到XML。

我没有在任何地方找到任何可用的答案。 似乎早在2003年,MS就在谈论创建XPathDocument2或实现我所要求的东西(书籍谈论即将发布的版本提到它),但它似乎没有被执行。 所以这是我尝试解决方案:

使用XPathDocument / XPathNavigator,并为Change / Delete / Insert添加事件处理程序。 对于每个事件,将记录放在DataTable {XPath |中 OldValue | NewValue}表示更改。 准备好提交时,发送表格然后清除它。 如果取消,请使用表信息撤消XPathDocument中的更改。

我还没有实现这个,但它似乎可以服务。

我曾多次试图找到一个免费或开源的XML diff工具,但从未挖出任何真正符合要求的东西。 从本质上讲,你正在寻找树差异,这本身就是一个完整的光盘 。 我猜你使用XML的事实是从属的,因为它只是另一种forms的树。 您“只需”定义指定节点的内容。

虽然树编辑距离的分解算法计算了两棵树之间的距离,但我怀疑你可以对它进行变换以给你所有的变化,因为它是距离测量的基础。 如何在检测后传达更改,完全取决于您。 这可能从XML到JSON。 请注意,算法的作者提到他们在几十行中创建了一个Python版本,所以如果你放弃一行,他们可能会有所帮助。

如果你能做到这一点,看起来你可能是第一个发布实用概念certificate的人:)

你在这里遇到的问题是XML只是表示数据的一种forms,它不一定是数据本身。 这是您正在使用的某种XML编辑器,还是XML只是传输?

如果您正在谈论xml作为传输,那么当您谈到发送XML更改描述时,您可能希望在生成更改本身时生成这些更改描述,并且每次更改描述都不会是在与原始数据相同的模式中。

此外,数据集可以执行此操作的原因是因为数据集中的每一行都具有已知的唯一键。 因此,可以为行而不是整个集发回更改。 XML不能像那样工作,每一行都没有唯一的密钥。 XPath可以用作更改定位器,但这比使用足够的编辑发送整个文档效率更低。

为什么不简单地将XML视为使用任何标准修补算法的文本? (看看Git或Hg的来源)