教程和示例

通用匹配与标识映射方案:
如何创建“标识映射方案”以改进比较结果

考虑左边和右边稍微有点不同的两个版本的示例 XML 文件。假定元素 extension-point 由属性 id 唯一标识。文本差别以粗体显示。

<?xml version="1.0" encoding="UTF-8"?>

<plugin
   name="%Plugin.name"
   id="org.eclipse.ui"
   version="1.0"
   provider-name="Object Technology International, Inc."
   class="org.eclipse.ui.internal.WorkbenchPlugin">

<extension-point name="%ExtPoint.editorMenus " id="editorActions"/>
<extension-point name="%ExtPoint.popupMenus " id="popupMenus"/>
<extension-point name="%ExtPoint.importWizards" id="importWizards"/>

</plugin>

  

<?xml version="1.0" encoding="UTF-8"?>

<plugin
   name="%Plugin.name"
   id="org.eclipse.ui"
   version="1.0"
   provider-name="Object Technology International, Inc."
   class="org.eclipse.ui.internal.WorkbenchPlugin">

<extension-point name="%ExtPoint.editorMenus " id="editorActions"/>
<extension-point name="%ExtPoint.popupMenus " id="popupMenus"/>
<extension-point name="%ExtPoint.exportWizards" id="exportWizards"/>

</plugin>


假定应忽略元素的顺序。两个文档之间的结构差别在于:左边为 extension-point 元素,而右边的 id="importWizards" 被替换为新的带有 id="exportWizards"extension-point。因为通用匹配算法(称为无序方法)忽略 XML 元素在文档中出现的顺序,所以使用这种方法可以获得以下差别树。

使用通用匹配算法的差别树

前两个 extension-point 元素是完全相同的,因此相匹配且不会显示在差别树中。两边各剩下第三个 extension-point 元素,因为具有相同的元素名称,也是匹配的。这样差别树显示左边的第三个 extension-point 元素和右边的第三个 extension-point 元素之间的差别。这些差别在于属性 idname 的值中。
但是,这不是我们想要看到的。我们想要差别树显示从左边除去 extension-point 元素并在右边添加新的 extension-point 元素。
为实现此目的,我们创建一个新的“标识映射方案”。可通过使用工具栏上适当的按钮来进行此操作。

创建新的标识映射方案

假定将“标识映射方案”称为 MyPlugin。现在从工具栏的下拉列表中选择“标识映射方案”MyPlugin

选择 MyPlugin 标识映射方案

并将它添加至以下映射:

从首选项页创建新的映射     使用上下文菜单创建新的映射

这可通过首选项页(左)或结构视图(右)中的上下文菜单来完成。
差别树现在变成如下所示:
(要刷新结构视图,单击工具栏中的下拉列表的 更新视图按钮 按钮。

使用 MyPlugin 标识映射方案的差别树

这是我们想要的并通过创建“标识映射方案”达到的比较结果。

XML 比较插件已附带用于插件文件的“标识映射方案”,可为特定插件文件定制它。

警告:
如果创建了“标识映射”,则假定该标识是唯一的,即,任何 XML 元素的名称和具有该标识的路径都是唯一的。否则,“标识映射方案”可能无法提供明确的差别树。
如果某个标识可能出现多次,则应该依赖通用算法。

另外,如果使用了“标识映射方案”而未对某些元素指定标识映射,则将使用无序比较方法,即,按元素的相似性来匹配元素而不是按元素出现在文档中的顺序来匹配它们。要指定按出现顺序比较某个元素的子代,请参阅下一节有关“有序”条目的内容。

添加有序条目

有序条目用来指定应以有序方式来比较 XML 元素(按其路径进行标识)的直系子代(排除属性),而不是以缺省无序方法来比较。
作为示例,考虑以下稍微有点不同的两个版本的 ANT 文件:

<?xml version="1.0" encoding="UTF-8"?>

<project name="org.junit.wizards" default="export" basedir="..">
   <target name="export" depends="build">
      <mkdir dir="${destdir}" />
      <delete dir="${dest}" />
      <mkdir dir="${dest}" />
      <jar
         jarfile="${dest}/JUnitWizard.jar"
         basedir="bin"
      />
</project>

  

<?xml version="1.0" encoding="UTF-8"?>

<project name="org.junit.wizards" default="export" basedir="..">
   <target name="export" depends="build">
      <mkdir dir="${destdir}"/>
      <mkdir dir="${dest}"/>
      <delete dir="${dest}"/>
      <jar
         jarfile="${dest}/JUnitWizard.jar"
         basedir="bin"
      />
      <copy file="plugin.xml" todir="${dest}"/>
</project>


两个文档之间的差别以粗体显示。已经交换了两个元素(<mkdir dir="${dest}"/><delete dir="${dest}"/>)并在目标元素后追加了一个新元素(<copy .../>)。
执行无序比较将产生以下差别树:

使用无序匹配的差别树

由于忽略了元素的顺序,差别树并未显示已交换两个元素的事实。
但是,从 ANT 的角度来看,这两个文档会导致大不相同的行为,因为 target 内的元素的顺序很重要。因此我们想要为目标创建有序条目以指示比较引擎以有序方式比较目标的直系子代。
通过先创建一个新的“标识映射方案”来实现。可使用工具栏中的适当按钮来完成。

创建新的标识映射方案

假定将“标识映射方案”称为 MyANT
现在从工具栏的下拉列表中选择“标识映射方案”MyANT 并将它添加到以下“有序条目”中:

从首选项页创建新的有序条目     使用上下文菜单创建新的有序条目

这可通过首选项页(左)或结构视图(右)中的上下文菜单来完成。
差别树现在变成如下所示:
(要刷新结构视图,单击工具栏中下拉列表的 更新视图按钮 按钮。

使用 MyANT 标识映射方案的差别树

这是我们想要的并通过创建“有序条目”达到的比较结果。

另外,还可使用“标识映射”(请参阅上一节)来唯一地标识有序子元素。尤其是在有许多更改时,这样做会改进比较结果。

XML 比较插件已附带用于 Ant 文件的“标识映射方案”,可为特定 ANT 文件定制它。