gpt4 book ai didi

java - xmlunit:ElementSelectors.conditionalBuilder 错误

转载 作者:行者123 更新时间:2023-12-01 08:53:33 27 4
gpt4 key购买 nike

所以我有以下输入、预期输出和实际输出 xml:

input.xml

<Request>
<EmailSubjectLine>Main Contact &amp; No Reported To</EmailSubjectLine>
<ProductRq>
<Signon>
<ClientDt>1/6/2017 11:25:45 AM</ClientDt>
<CustLangPref>en-US</CustLangPref>
</Signon>
<SvcRq>
<RqUID>xxxxxxxx-2802-xxxx-xxxx-bf8361xxxxxx</RqUID>
<NotificationRq>
<TransactionRequestDt>2017-01-06</TransactionRequestDt>
<Currency>USD</Currency>
</NotificationRq>
</SvcRq>
</ProductRq>
<!-- rest of input -->
</Request>

预期输出.xml

<ProductRq xmlns="http://test.org/standards/intake">
<Audit>
<TransID>Test</TransID>
</Audit>
<Signon>
<ClientDt>1/6/2017 11:25:45 AM</ClientDt>
<CustLangPref>en-US</CustLangPref>
</Signon>
<SvcRq>
<RqUID>xxxxxxxx-2802-xxxx-xxxx-bf8361xxxxxx</RqUID>
<NotificationRq>
<RqUID>Test</RqUID>
<TransactionRequestDt>2017-01-06</TransactionRequestDt>
<Currency>USD</Currency>
</NotificationRq>
</SvcRq>
<!-- rest of expected-output -->
</ProductRq>

实际输出.xml

<ProductRq xmlns="http://test.org/standards/intake">
<Audit>
<TransID>123534Abwe-asdcv-1258qw-asd</TransID>
</Audit>
<Signon>
<ClientDt>1/6/2017 11:25:45 AM</ClientDt>
<CustLangPref>en-US</CustLangPref>
</Signon>
<SvcRq>
<RqUID>xxxxxxxx-2802-xxxx-xxxx-bf8361xxxxxx</RqUID>
<NotificationRq>
<RqUID>CG-17Dawe-12354-Hw35Sf</RqUID>
<TransactionRequestDt>2017-01-06</TransactionRequestDt>
<Currency>USD</Currency>
</NotificationRq>
</SvcRq>
<!-- rest of actual-output -->
</ProductRq>

我将它们与以下 Diff 设置进行比较:

MyTest.java

        Diff diff = DiffBuilder
.compare(xmlExpectedOutput)
.withTest(xmlOutput)
.normalizeWhitespace()
.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.conditionalBuilder()
.whenElementIsNamed("Audit")
.thenUse(ElementSelectors.byXPath("./TransID", ElementSelectors.byName))
.whenElementIsNamed("NotificationRq")
.thenUse(ElementSelectors.byXPath("./RqUID", ElementSelectors.byName))
.elseUse(ElementSelectors.byNameAndText)
.build()
))
.checkForSimilar()
.build();

当我运行上述输入并与预期输出.xml 进行比较时,我得到以下差异:

[Expected child '{http://test.org/standards/intake}RqUID' but was 'null' - comparing <RqUID...> at /ProductRq[1]/SvcRq[1]/NotificationRq[1]/RqUID[1] to <NULL> (DIFFERENT), Expected child 'null' but was '{http://test.org/standards/intake}RqUID' - comparing <NULL> to <RqUID...> at /ProductRq[1]/SvcRq[1]/NotificationRq[1]/RqUID[1] (DIFFERENT)]

我不明白为什么我的元素选择器不起作用,我使用它是否不正确?我的目标是每当找到 TransmissionId 或 NotificationRq/RqUID 时,仅通过名称将它们与预期的输出版本进行匹配,否则使用其他元素的名称和文本,因为这些元素包含唯一生成的 id,这些 id 会更改每次测试运行并且无法预测(着眼于稍后创建更复杂的选择器,例如通过名称和属性比较 ProductRq,因为命名空间已添加到此)。我是否遗漏了一些东西,我是否能够将 2 个 XPath 选择器组合在一起,而不是几个 when/then 行和默认情况?

注意:xml是通过xslt转换的。 PROoductRq 上的命名空间在源文档中不存在;复制源,将命名空间添加到 ProductRq,然后与一些元素删除/修改/添加一起发送以进行输出

最佳答案

XMLUnit 表示 NotificationRq 内的 RqUID 元素不匹配,当然它们是不同的。

.whenElementIsNamed("NotificationRq")
.thenUse(ElementSelectors.byXPath("./RqUID", ElementSelectors.byName))

表示:当 XMLUnit 尝试为 NotificationRq 元素查找合作伙伴时,它必须搜索具有 RqUID 子元素的 NotificationRq - 并且仅使用 RqUID 元素。

它不会为任何其他元素设置任何规则,特别是 RqUID 本身。对于 RqUID 元素,应用默认规则并且

.elseUse(ElementSelectors.byNameAndText)

表示:XMLUnit 仅接受两个元素作为对,前提是它们的名称和嵌套文本匹配。但所涉及的 RqUID 元素的情况并非如此。

你的整个ElementSelector

  • 如果 Audit 具有任意内容的 TransID 子项,则匹配它们。
  • 如果 NotificationRq 具有任意内容的 RqUID,则匹配它们。
  • 否则使用元素名称和嵌套文本

这不适合你的例子。查看您可能想要的 XML

  • 通过元素名称和嵌套文本匹配几乎所有内容(尽管从示例中元素名称就足够了)
  • 忽略 AuditTransId 子级的嵌套文本
  • 忽略 NotificationRqRqUID 子级的嵌套文本

对于“名为 foo 的元素,如果它是名为 bar 的元素的子元素”,没有内置谓词,它可能类似于

Predicate<Element> transIdInAudit = e -> {
if (e == null || e.getParentNode() == null) {
return false;
}
return "TransID".equals(e.getLocalName()) && "Audit".equals(e.getParentNode().getLocalName());
};

您可能希望使其具有普遍性:-)

这样你就可以使用

.withNodeMatcher(new DefaultNodeMatcher(ElementSelectors.conditionalBuilder()
.when(transIdInAudit)
.thenUse(ElementSelectors.byName)
.when(rqUIDInNotificationRq) // similar to transIdInAudit
.thenUse(ElementSelectors.byName)
.elseUse(ElementSelectors.byNameAndText)
.build())

也许您真的想匹配 SvcRq(如果它们具有匹配的 RqUID),也许不是。如果是这样,您将使用当前用于 NotificationRq 的结构。

这本身并不足以忽略匹配的 TransIdRqUID 元素的嵌套文本,它只会确保 XMLUnit 将选择您想要的节点使用。对于嵌套文本,您需要一个 DifferenceEvaluator

鉴于您默认使用 ElementSelectors.byNameAndText,您知道所有匹配节点的嵌套文本都是相同的,除了您想要忽略内容的两个特定元素之外。所以一个 DifferenceEvaluator 就像

DifferenceEvaluators.chain(DifferenceEvaluators.Default,
DifferenceEvaluators.downgradeDifferencesToEqual(ComparisonType.TEXT_VALUE))

应该可以。

关于java - xmlunit:ElementSelectors.conditionalBuilder 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42207994/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com