因此,我尝试使用 Microsoft 提供的 XMLDiff 来查找两个 XML 文件之间的差异。目的是比较两个 XML 文件并找出确切的差异,以便我可以对它们进行审计跟踪。这些文件可能具有不同的结构(添加或删除节点)。
然而,当涉及到嵌套重复结构时,XMLDiff 似乎给了我一个意想不到的输出。
示例 XML #1(原始):
<pd:AP xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pd="http://www.ascentn.com/bpm/XMLSchema">
<pd:processFields />
<pd:formFields>
<pd:TextBox1>val 1</pd:TextBox1>
<pd:DropdownList1>Option 4</pd:DropdownList1>
<pd:TextBox2>val 2</pd:TextBox2>
<pd:CheckBox1>Option 2;Option 3;Option 4</pd:CheckBox1>
<pd:SubForm1_SubForm>
<pd:SubForm1>
<pd:TextBox3>val 3</pd:TextBox3>
<pd:DropdownList3>Option 3</pd:DropdownList3>
<pd:DropdownList2>Option 2</pd:DropdownList2>
</pd:SubForm1>
<pd:SubForm1>
<pd:TextBox3>val 4</pd:TextBox3>
<pd:DropdownList3>Option 5</pd:DropdownList3>
<pd:DropdownList2>Option 3</pd:DropdownList2>
</pd:SubForm1>
</pd:SubForm1_SubForm>
</pd:formFields>
</pd:AP>
示例 XML #2(已修改):
<pd:AP xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pd="http://www.ascentn.com/bpm/XMLSchema">
<pd:processFields />
<pd:formFields>
<pd:TextBox1>val 1.changed</pd:TextBox1>
<pd:DropdownList1>Option 4</pd:DropdownList1>
<pd:TextBox2>val 2</pd:TextBox2>
<pd:CheckBox1>Option 2;Option 3;Option 4</pd:CheckBox1>
<pd:SubForm1_SubForm>
<pd:SubForm1>
<pd:TextBox3>val 3.changed</pd:TextBox3>
<pd:DropdownList3>Option 3</pd:DropdownList3>
<pd:DropdownList2>Option 2</pd:DropdownList2>
</pd:SubForm1>
<pd:SubForm1>
<pd:TextBox3>val 4</pd:TextBox3>
<pd:DropdownList3>Option 5</pd:DropdownList3>
<pd:DropdownList2>Option 11</pd:DropdownList2>
</pd:SubForm1>
<pd:SubForm1>
<pd:TextBox3>val 6</pd:TextBox3>
<pd:DropdownList3>Option 3</pd:DropdownList3>
<pd:DropdownList2>Option 3</pd:DropdownList2>
</pd:SubForm1>
</pd:SubForm1_SubForm>
</pd:formFields>
</pd:AP>
我得到的 XML 文件是:
<?xml version="1.0" encoding="utf-8"?>
<xd:xmldiff version="1.0" srcDocHash="12260906919056999448" options="IgnoreChildOrder IgnoreNamespaces IgnorePrefixes " fragments="no" xmlns:xd="http://schemas.microsoft.com/xmltools/2002/xmldiff">
<xd:node match="1">
<xd:node match="2">
<xd:node match="5">
<xd:add type="1" name="SubForm1" ns="http://www.ascentn.com/bpm/XMLSchema" prefix="pd">
<xd:add>
<pd:DropdownList2 xmlns:pd="http://www.ascentn.com/bpm/XMLSchema">Option 11</pd:DropdownList2>
</xd:add>
<xd:add match="/1/2/5/2/1-2" opid="1" />
</xd:add>
<xd:node match="1">
<xd:node match="1">
<xd:change match="1">val 3.changed</xd:change>
</xd:node>
</xd:node>
<xd:node match="2">
<xd:add>
<pd:TextBox3 xmlns:pd="http://www.ascentn.com/bpm/XMLSchema">val 6</pd:TextBox3>
<pd:DropdownList3 xmlns:pd="http://www.ascentn.com/bpm/XMLSchema">Option 3</pd:DropdownList3>
</xd:add>
<xd:remove match="1-2" opid="1" />
</xd:node>
</xd:node>
<xd:node match="1">
<xd:change match="1">val 1.changed</xd:change>
</xd:node>
</xd:node>
</xd:node>
<xd:descriptor opid="1" type="move" />
</xd:xmldiff>
这很奇怪,因为如果您看到 pd:SubForm1 的第二个节点,我只更改了其中的第三个元素。为什么它会在删除并重新添加节点时将其拾取?它不应该将其标记为更改吗?
如果我更改 pd:SubForm1 中的前两个节点,那么它会将其拾取为已更改,但一旦第三个(最后一个节点更改),它就会将其标记为删除和添加(即使前两个未更改)。
我设置了 IgnoreChildOrder 标志
XmlDiff xmldiff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder |
XmlDiffOptions.IgnoreNamespaces |
XmlDiffOptions.IgnorePrefixes);
知道如何绕过这个或任何关于如何以更好的方式绕过它的想法吗?
任何帮助将不胜感激。