Doc4j:由于不同的元素类型,比较两个文档失败

时间:2017-08-09 17:25:01

标签: java xml jaxb docx4j javax

我尝试为我编写的Docx4J生成器编写一些JUnit测试。 我想比较我的生成器的输出节点和我想从字符串加载的预期节点。

所以,我创造了我的"实际"节点(生成器输出)如下:

Node xmlNodeActual = XmlUtils.marshaltoW3CDomDocument(actual).getDocumentElement();

其中"实际"是我的生成器创建的对象。

对于我的预期"我写了以下代码:

Document doc = docBuilder.parse(new InputSource(new ByteArrayInputStream(strXmlNode.getBytes("utf-8")))):
Node xmlNodeExpected = doc.getDocumentElement();

strXmlNode是一个包含预期xml的字符串。 虽然我的两个节点在视觉差异方面是相同的,但是调用以下内容会产生“假”错误。结果:

xmlNodeActual.isEqualNode(xmlNodeExpected)

我怀疑原因是两个节点的运行时类型不同:

  • xmlNodeActual:org.apache.xerces.dom.DeferredElementImpl
  • xmlNodeExpected:org.apache.xerces.dom.ElementNSImpl

我喜欢我的测试设计,因为它可以让我为大型发电机快速编写大量测试用例。但是,我没有看到将这种方法与" isEqualNode"结合使用的方法。 我是否必须编写自己的比较器,或者是否有一种我不知道的方法来确保节点的类型是相同的?

3 个答案:

答案 0 :(得分:0)

使用这样的方法的一个问题是它只给出一个布尔答案,它没有告诉你两个节点之间的实际差异是什么。另一个问题是你无法告诉它你认为重要的差异:例如(据我所知)冗余命名空间声明被这种特殊方法认为是重要的。空白通常是有问题的。我使用XPath deep-equal()方法遇到了同样的问题,结果写了saxon:deep-equal变体。但我现在更喜欢使用一组XPath断言来测试预期结果。 W3C XSLT测试套件使用这种技术测试断言如下:

<result>
     <all-of>
        <assert>/root/p[1]/text()[1] = 'Tekst '</assert>
        <assert>/root/p[1]/text()[2] = ' etc..'</assert>
        <assert>/root/p[2]/text()[1] = 'Tekst '</assert>
        <assert>/root/p[2]/text()[2] = ' etc..'</assert>
     </all-of>
  </result>

我曾经做过一个小工具,可以从XML文档中生成这样的断言列表,但我现在倾向于手动执行它们。最大的好处是,如果出现问题,诊断程序将告诉您哪个断言失败。

答案 1 :(得分:0)

答案 2 :(得分:0)

请注意,@ Michael Kay和@JasonPlutext提供了有关如何测试XML输出的有趣且更好的替代方案,您可能需要考虑这些方法。

至于我的具体问题和问题,即简单地将两个XML节点与&#34; isEqualNode&#34;进行比较,一个源于输入字符串,一个源于数据转换,我必须执行以下操作:而不是解析字符串,我可以通过InputStream解组它,从而获得所需的节点类型。

@Rule
public ActivityTestRule activityRule = new ActivityTestRule<>(LoginActivity.class);

@Before
public void setUp() {
    onView(withId(R.id.et_username_login))
            .perform(typeText(Credentials.USERNAME), ViewActions.closeSoftKeyboard());
    onView(withId(R.id.et_password_login))
            .perform(typeText(Credentials.PASSWORD), ViewActions.closeSoftKeyboard());
    onView(withId(R.id.btn_login)).perform(click());
}
@Test
public void onAllEventTabTest() {
    onView(withId(R.id.ll_tab_1)).perform(click());
}

@Test
public void formPacketTabTest() {
    onView(withId(R.id.ll_tab_2)).perform(click());
}

这会产生相同的节点类型,并按预期用于我的设置。尽管如此,这种比较两个XML树的方法有一些缺陷,正如Michael Kay所指出的那样,所以不要认为这是一种最佳实践,而是采用另一种方法来进行一般的XML比较。