我们正在使用JAXB将XML配置文件解析为Java对象。 XML文件是版本化的,在将版本1.0和2.0加载到对象后,我们希望递归地比较相同但未知类型的两个对象(对于所有类型的事物有许多不同的配置)和它们的字段值并打印出差异
对象可能如下所示。
@XmlRootElement(name = "HelloWorld")
public class HelloWorldConfiguration {
private List<HelloWorldObject> helloWorldObjects = new ArrayList<HelloWorldObject>();
public HelloWorldConfiguration() {
HelloWorldObject o = new HelloWorldObject();
helloWorldObjects.add(o);
helloWorldObjects.add(o);
helloWorldObjects.add(o);
helloWorldObjects.add(o);
helloWorldObjects.add(o);
}
@XmlElement(name = "helloWorldObject")
public List<HelloWorldObject> getHelloWorldObjects() {
return helloWorldObjects;
}
public void setHelloWorldObjects(List<HelloWorldObject> helloWorldObjects) {
this.helloWorldObjects = helloWorldObjects;
}
}
public class HelloWorldObject {
private Stage firstName = new Stage("Tony");
private Stage secondName = new Stage("Stark");
public Stage getFirstName() {
return firstName;
}
public void setFirstName(Stage firstName) {
this.firstName = firstName;
}
public Stage getSecondName() {
return secondName;
}
public void setSecondName(Stage secondName) {
this.secondName = secondName;
}
}
例如,我们希望了解有关上述HelloWorldConfiguration对象的以下更改?
我的问题如下。
答案 0 :(得分:1)
免责声明。我是JAXB2 Basics插件包的作者,其中包含JAXB2 Equals plugin。
如果从XML Schema生成类,则在此用例中JAXB2 Equals plugin可能对您有用。
JAXB2 Equals plugin能够生成equals
方法,这些方法执行JAXB类实例的深层结构遍历值比较:
public boolean equals(Object object) {
final EqualsStrategy strategy = JAXBEqualsStrategy.INSTANCE;
return equals(null, null, object, strategy);
}
public boolean equals(ObjectLocator thisLocator, ObjectLocator thatLocator, Object object, EqualsStrategy strategy) {
if (!(object instanceof PurchaseOrderType)) {
return false;
}
if (this == object) {
return true;
}
final PurchaseOrderType that = ((PurchaseOrderType) object);
{
USAddress lhsShipTo;
lhsShipTo = this.getShipTo();
USAddress rhsShipTo;
rhsShipTo = that.getShipTo();
if (!strategy.equals(LocatorUtils.property(thisLocator, "shipTo", lhsShipTo), LocatorUtils.property(thatLocator, "shipTo", rhsShipTo), lhsShipTo, rhsShipTo)) {
return false;
}
}
{
USAddress lhsBillTo;
lhsBillTo = this.getBillTo();
USAddress rhsBillTo;
rhsBillTo = that.getBillTo();
if (!strategy.equals(LocatorUtils.property(thisLocator, "billTo", lhsBillTo), LocatorUtils.property(thatLocator, "billTo", rhsBillTo), lhsBillTo, rhsBillTo)) {
return false;
}
}
// ...
return true;
}
我希望你有这个想法。您可以提供一个“定位器”,用于跟踪被比较事物的位置,以及一个用于比较各个值的策略。
结果你可以:
整个事情都是无反射的,因此非常快。
以下是another project的摘录。这是我在比较“之前”和“之后”对象的测试之一,并记录差异。
final EqualsStrategy strategy = new org.jvnet.hyperjaxb3.lang.builder.ExtendedJAXBEqualsStrategy() {
@Override
public boolean equals(ObjectLocator leftLocator,
ObjectLocator rightLocator, Object lhs, Object rhs) {
if (!super.equals(leftLocator, rightLocator, lhs, rhs)) {
logger.debug("Objects are not equal.");
super.equals(leftLocator, rightLocator, lhs, rhs);
logger.debug("Left: "
+ (lhs == null ? "null" : lhs.toString()));
if (leftLocator != null) {
logger.debug("At [" + leftLocator.getPathAsString()
+ "].");
}
logger.debug("Right: "
+ (rhs == null ? "null" : rhs.toString()));
if (rightLocator != null) {
logger.debug("At [" + rightLocator.getPathAsString()
+ "].");
}
return false;
} else
{
return true;
}
}
};
另一方面,这种方法并不是真正的“差异”,因为您可能从VCS中了解它。它只说某些东西不同,但不计算任何“最短编辑距离”。