当前位置: 首页 > 面试题库 >

比较两个JSON时忽略特定的节点/属性

锺离德运
2023-03-14
问题内容

我想比较两个JSON字符串,它们是一个巨大的层次结构,并且想知道它们的值在哪里不同。但是某些值是在运行时生成的,并且是动态的。我想从比较中忽略那些特定的节点。

我目前正在使用来自 org.SkyScreamer的JSONAssert 进行比较。它为我提供了不错的控制台输出,但没有忽略任何属性。

对于前。

java.lang.AssertionError messageHeader.sentTime
expected:null
got:09082016 18:49:41.123

现在这是动态的,应该忽略。就像是

JSONAssert.assertEquals(expectedJSONString, actualJSONString,JSONCompareMode, *list of attributes to be ignored*)

如果有人建议使用JSONAssert解决方案,那将是很好的。但是,也欢迎其他方式。


问题答案:

您可以为此使用自定义。例如,如果您需要忽略名为“ timestamp”的顶级属性,请使用:

JSONAssert.assertEquals(expectedResponseBody, responseBody,
            new CustomComparator(JSONCompareMode.LENIENT,
                new Customization("timestamp", (o1, o2) -> true)));

也可以使用路径表达式,例如“
entry.id”。在自定义中,您可以使用任何喜欢的方法比较两个值。上面的示例始终返回true,无论期望值和实际值是多少。如果需要,您可以在那里做更复杂的事情。

完全可以忽略多个属性的值,例如:

@Test
public void ignoringMultipleAttributesWorks() throws JSONException {
    String expected = "{\"timestamp\":1234567, \"a\":5, \"b\":3 }";
    String actual = "{\"timestamp\":987654, \"a\":1, \"b\":3 }";

    JSONAssert.assertEquals(expected, actual,
            new CustomComparator(JSONCompareMode.LENIENT,
                    new Customization("timestamp", (o1, o2) -> true),
                    new Customization("a", (o1, o2) -> true)
            ));
}

使用自定义项时有一个警告:要以自定义方式比较其值的属性必须存在于实际JSON中。如果即使属性根本不存在,也希望比较成功,则必须重写CustomComparator,例如:

@Test
public void extendingCustomComparatorToAllowToCompletelyIgnoreCertainAttributes() throws JSONException {
    // AttributeIgnoringComparator completely ignores some of the expected attributes
    class AttributeIgnoringComparator extends CustomComparator{
        private final Set<String> attributesToIgnore;

        private AttributeIgnoringComparator(JSONCompareMode mode, Set<String> attributesToIgnore, Customization... customizations) {
            super(mode, customizations);
            this.attributesToIgnore = attributesToIgnore;
        }

        protected void checkJsonObjectKeysExpectedInActual(String prefix, JSONObject expected, JSONObject actual, JSONCompareResult result) throws JSONException {
            Set<String> expectedKeys = getKeys(expected);
            expectedKeys.removeAll(attributesToIgnore);
            for (String key : expectedKeys) {
                Object expectedValue = expected.get(key);
                if (actual.has(key)) {
                    Object actualValue = actual.get(key);
                    compareValues(qualify(prefix, key), expectedValue, actualValue, result);
                } else {
                    result.missing(prefix, key);
                }
            }
        }
    }

    String expected = "{\"timestamp\":1234567, \"a\":5}";
    String actual = "{\"a\":5}";

    JSONAssert.assertEquals(expected, actual,
            new AttributeIgnoringComparator(JSONCompareMode.LENIENT,
                    new HashSet<>(Arrays.asList("timestamp")))
            );
}

(使用这种方法,您仍然可以使用“自定义”以所需的方式比较其他属性的值。)



 类似资料:
  • 问题内容: 我有两个XML文件: 在比较这两个文件时,我不得不忽略Node 的属性:。 我正在使用: 大多数在线解决方案建议实施: 也尝试过该操作,但这会忽略所有具有属性ID的节点,而我想忽略特定节点的属性: 我的Test类中的调用方法: 有人可以建议我一种使用XMLUnit 2.x的新方法来实现此目标,请相应地提供帮助。 提前致谢。 问题答案: 如果您确实愿意,可以使用一个。您只需要做的就是测试

  • 我想比较两个较小的有向python igraph图,包括边或节点上的所有属性及其值,以及边的方向。python igraph包中有这样的函数吗? 我看到了G1.isomorphic(G2)和相关的,但是它们似乎不适用于属性,也不适用于边缘的方向性 例子:

  • 问题内容: 假设我有两个xml字符串 如何编写一个比较这两个字符串并忽略元素顺序的测试? 我希望测试尽可能短,没有10行XML解析等的位置。我正在寻找一个简单的断言或类似内容。 我有这个(不起作用) 问题答案: 我原来的答案已经过时了。如果必须再次构建它,我将使用xmlunit 2和xmlunit- matchers。请注意,对于xml单元,不同的顺序始终是“相似”而不是相等。 如果有人仍然不想使

  • 问题内容: 我有这个间隔,当前每5秒执行一次ajax请求。我对声明有疑问。我的代码总是输入它,并且两个json值完全相同,为什么它认为它们不同? 编辑 这是控制台输出(虚线是分隔请求,它不在实际输出中) 问题答案: 不能保证以相同的方式序列化JSON对象,也不能保证属性以相同的顺序进行序列化,使用并不是测试对象相等性的好方法。 一个更好的例子是这样的函数(前一段时间在互联网上找到,希望我能感谢原始

  • 当我执行时,结果显然是。但是我想忽略“nullable”参数,不管它是false还是true,如果结构相同,它应该返回。 有可能吗?