我正在寻找一种方法来导入和导出XML数据文档的更改列表(不规则结构;不自然地适合DataSet)。
如果我有一个常规结构,我将使用DataTable,我可以评估哪些记录已被编辑,然后提交或取消更改,我还可以传输所需更改的数据包。
如何使用XML数据执行此操作?
如果没有一个好的答案,我认为我最好的办法就是使用DataTable和[XPath,Value]方案,尽管存储效率低,导航困难。
我希望对文档进行更改(使用XPath或LINQ或数据绑定控件或其他),然后记住更改并仅通过TCP发送更改。
然后我想收到另一个更改列表并将其应用于XML文档。我不想发送整个文档的大小,因为我需要知道并评估发送的更改。
(只是为了澄清:我的程序需要发送和接收文档更改。管道的另一端不是基于.net,并且不是此问题的一部分。)
答案 0 :(得分:1)
您是否需要对此更改采取行动或仅存储它们,如果您只想存储更新的版本,则可以使用二进制差异算法来传递2 xml文件之间的差异。然后以不同的方式更新存储的版本。对此的好算法是bifdiff 可以找到C#版本here。
另一个方法是使用MS
中的这个XmlDiff类答案 1 :(得分:1)
如果您使用了NodeInserted,NodeDeleted,NodeChanged等XmlDocument事件,则可以构建此类更改的列表,然后在另一个副本上执行它们。如果更改总量超过文档本身,则可以发送文档。压缩xml数据也有帮助。
除此之外我没有看到任何其他简单的方法。
答案 2 :(得分:0)
获取结构不规则的XML数据时;不自然地拟合DataSet,并且您希望对象模型轻松处理数据。您可以使用XML Schema Definition Tool (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
-Command Line
这是查看所有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标志修改类。我敢肯定,一旦你有了可以使用的课程,就很容易发现差异。
答案 3 :(得分:0)
要将任何XML数据加载到DataSet
,您必须提供相应的架构
请参阅Deriving DataSet Relational Structure from XML Schema (XSD)。
此外,DataSet
/ DataTable
不适用于XML文档。他们可以从导出数据,并导出数据到XML。
答案 4 :(得分:0)
我在任何地方都找不到任何可用的答案。似乎早在2003年MS就在谈论创建一个XPathDocument2或实现了我所要求的东西(书籍谈论即将发布的版本提到它),但它似乎没有被执行。所以这是我尝试解决方案:
使用XPathDocument / XPathNavigator,并为Change / Delete / Insert添加事件处理程序。对于每个事件,将记录放在DataTable {XPath |中OldValue | NewValue}表示更改。准备好提交时,发送表格然后清除它。如果取消,请使用表信息撤消XPathDocument中的更改。
我还没有实现这个,但它似乎可以服务。
答案 5 :(得分:0)
我曾多次试图找到一个免费或开源的XML差异工具,但从来没有挖出任何真正符合要求的东西。从本质上讲,你正在研究树差异,它本身就是a whole discpline。我猜,你使用XML的事实是从属的,因为它只是另一种形式的树。您“只需”定义指定节点的内容。
虽然Decomposition Algorithm for Tree Edit Distance计算了2棵树之间的距离,但我怀疑你可以对它进行变换以给你所有的变化,因为它是距离测量的基础。如何在检测后传达更改,完全取决于您。这可能从XML到JSON。请注意,算法的作者提到他们在几十行中创建了一个Python版本,所以如果你放弃一行,他们可能会有所帮助。
如果你能做到这一点,看起来你可能是第一个发表实际概念验证的人:)
答案 6 :(得分:0)
你遇到的问题是XML只是表示数据的一种形式,它不一定是数据本身。这是您正在使用的某种XML编辑器,还是XML只是传输?
如果您正在谈论xml作为传输,那么当您谈到发送XML更改描述时,您可能希望在生成更改本身时生成这些更改描述,并且每次更改描述都有可能获胜与原始数据处于相同的模式中。
此外,数据集可以执行此操作的原因是因为数据集中的每一行都具有已知的唯一键。因此,可以为行而不是整个集发回更改。 XML不能像那样工作,每一行都没有唯一的密钥。 XPath可以用作更改定位器,但这比使用足够的编辑发送整个文档效率更低。
为什么不简单地将XML视为使用任何标准修补算法的文本? (查看Git或Hg的来源)