4

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

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

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

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

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

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

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

4

7 回答 7

1

您需要对这些更改采取行动还是只存储它们,如果您只想存储更新的版本,您可以使用二进制差异算法来传递 2 个 xml 文件之间的差异。然后以不同的方式更新存储版本。很好的算法是bifdiff 可以在这里找到 C# 版本。

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

于 2012-09-05T21:10:42.333 回答
1
  1. 你怎么想只发送更改?
  2. 您希望每次都有很多变化还是只是微小的变化?
  3. 你需要考虑什么样的改变?
  4. 您是否尝试跨流程边界维护同一文档的副本?
  5. 您将如何解决冲突的更改?
  6. 您是否要在更改传播之前锁定 xml 文档?
  7. 两个副本是独立的,还是一个是主副本?

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

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

于 2012-09-07T10:31:57.550 回答
0

当你得到结构不规则的 XML 数据时;不适合 DataSet 并且您希望对象模型轻松处理数据。您可以使用带有 /classes 选项的XML 架构定义工具 (Xsd.exe)从 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。 -开始-所有程序
-Visual Studio -工具 - 命令行



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

xsd /?

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

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

这将生成一个 csharp 文件,其中包含表示 XML 的类。您可能希望将其重构为单独的类文件,注意单个文件中的重复类通过命名空间消除歧义。无论哪种方式,这些类都不会是所有 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 标志修改类。我敢肯定,尽管一旦您有了要使用的课程,就很容易检测到差异。

于 2012-09-02T02:34:21.460 回答
0

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

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

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

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

于 2012-09-06T22:46:16.657 回答
0

要将任何 XML 数据加载到DataSet中,您必须提供相应的模式。
请参阅Deriving DataSet Relational Structure from XML Schema (XSD)

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

于 2012-09-04T10:54:57.520 回答
0

我之前曾多次尝试寻找免费或开源的 XML diff 工具,但从未找到任何真正符合要求的东西。从本质上讲,您正在查看树差异,这本身就是一个完整的学科。我想,您使用 XML 的事实从属于这一点,因为它只不过是另一种形式的树。您“只”需要定义指定节点的内容。

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

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

于 2012-09-06T20:56:38.653 回答
0

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

使用 XPathDocument/XPathNavigator,并为更改/删除/插入添加事件处理程序。对于这些事件中的每一个,在 DataTable {XPath | 旧值 | NewValue} 表示更改。准备好提交时,将表发送过去然后清除它。如果改为取消,请使用表信息撤消 XPathDocument 中的更改。

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

于 2012-09-05T15:43:08.077 回答