#apache-poi #xmlbeans #apache-poi-4
#apache-poi #xmlbeans #apache-poi-4
Вопрос:
Я пытаюсь использовать org.apache.poi.xwpf.usermodel.XWPFNumbering.getIdOfAbstractNum(XWPFAbstractNum abstractNum)
для проверки, существует ли заданный abstractNum или нет. Этот вызов заканчивается:
CTAbstractNumImpl(XmlComplexContentImpl).equal_to(XmlObject) line: 79
CTAbstractNumImpl(XmlObjectBase).valueEqualsImpl(XmlObject) line: 2393
CTAbstractNumImpl(XmlObjectBase).valueEquals(XmlObject) line: 2434
XWPFNumbering.getIdOfAbstractNum(XWPFAbstractNum) line: 222
...
К сожалению, org.apache.xmlbeans.impl.values.XmlComplexContentImpl.equal_to(XmlObject)
не реализовано должным образом и всегда возвращает true:
public boolean equal_to(XmlObject complexObject)
{
if (!_schemaType.equals(complexObject.schemaType()))
return false;
// BUGBUG: by-value structure comparison undone
return true;
}
Есть ли альтернатива для глубокого сравнения таких объектов xml или для выяснения, существует ли абстрактная нумерация?
Ответ №1:
К счастью, здесь был старый пост, к которому прилагается решение: <a rel="noreferrer noopener nofollow" href="https:///mail-archives.apache.org/mod_mbox/xml-xmlbeans-user/200310.mbox/» rel=»nofollow noreferrer»>http://mail-archives.apache.org/mod_mbox/xml-xmlbeans-user/200310.mbox/
Это слегка измененный контент, который позволяет сравнивать два XML-объекта, вызывая метод lenientlyCompareTwoXmlStrings(XmlObject, XmlObject)
:
package bookmarks;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.impl.common.QNameHelper;
import org.apache.xmlbeans.impl.common.XmlWhitespace;
/**
* This originates from an author called Dmitri.Coleba, see attached source here:
* http://mail-archives.apache.org/mod_mbox/xml-xmlbeans-user/200310.mbox/
*
* <p>
* Deep comparison of two xml objects.
*
* @author Markus Pscheidt
*
*/
public class XBeanCompare {
public static class Diagnostic {
private StringBuffer message = new StringBuffer();
void add(String s) {
message.append(s).append("n");
}
public String toString() {
return message.toString();
}
}
/**
* Provides a utility to compare the xml inside the two strings.
*
* @return true if the xml inside the two strings is the same
*/
public static boolean lenientlyCompareTwoXmlStrings(XmlObject actualObj, XmlObject expectObj, Diagnostic diag) {
boolean match = true;
XmlCursor cur1 = actualObj.newCursor();
XmlCursor cur2 = expectObj.newCursor();
cur1.toFirstChild();
cur2.toFirstChild();
while (cur1.currentTokenType() != XmlCursor.TokenType.STARTDOC) {
if (!compareNamesAndAttributes(cur1, cur2, diag)) {
match = false;
}
boolean hasChildren1 = cur1.toFirstChild();
boolean hasChildren2 = cur2.toFirstChild();
if (hasChildren1 != hasChildren2) {
diag.add("Topology differs: one document has " "children where the other does not ("
QNameHelper.pretty(cur1.getName()) ", " QNameHelper.pretty(cur2.getName()) ")."); // TODO:
// where?
match = false;
if (hasChildren1) {
cur1.toParent();
hasChildren1 = false;
}
if (hasChildren2) {
cur2.toParent();
hasChildren2 = false;
}
} else if (hasChildren1 == false) {
if (!wsCollapseEqual(cur1.getTextValue(), cur2.getTextValue())) {
diag.add("Value '" cur1.getTextValue() "' differs from value '" cur2.getTextValue() "'.");
match = false;
}
}
if (hasChildren1)
continue;
for (;;) {
boolean hasSibling1 = cur1.toNextSibling();
boolean hasSibling2 = cur2.toNextSibling();
if (hasSibling1 != hasSibling2) {
diag.add("Topology differs: one document has " "siblings where the other does not."); // TODO:
// where?
hasSibling1 = false;
hasSibling2 = false;
}
if (hasSibling1)
break;
cur1.toParent();
cur2.toParent();
if (cur1.currentTokenType() == XmlCursor.TokenType.STARTDOC)
break;
}
}
return match;
}
private static boolean compareNamesAndAttributes(XmlCursor cur1, XmlCursor cur2, Diagnostic diag) {
if (!cur1.getName().equals(cur2.getName())) {
diag.add("Element names '" QNameHelper.pretty(cur1.getName()) "' and '"
QNameHelper.pretty(cur2.getName()) "' do not match.");
return false;
}
String elemName = QNameHelper.pretty(cur1.getName());
boolean more = cur1.toFirstAttribute();
if (more) {
for (; more; more = cur1.toNextAttribute()) {
String text1 = cur1.getTextValue();
String text2 = cur2.getAttributeText(cur1.getName());
if (text2 == null) {
diag.add("Attribute '" QNameHelper.pretty(cur1.getName()) "' " " of element '" elemName
"' not present.");
return false;
}
if (!wsCollapseEqual(text1, text2)) {
diag.add("Attribute values for '" QNameHelper.pretty(cur1.getName()) "' " " of element '"
elemName "' don't match.");
return false;
}
}
cur1.toParent();
}
more = cur2.toFirstAttribute();
if (more) {
for (; more; more = cur2.toNextAttribute()) {
String text1 = cur1.getAttributeText(cur2.getName());
if (text1 == null) {
diag.add("Attribute '" QNameHelper.pretty(cur2.getName()) "' " " of element '" elemName
"' not present.");
return false;
}
}
cur2.toParent();
}
return true;
}
private static boolean wsCollapseEqual(String s1, String s2) {
String s1c = XmlWhitespace.collapse(s1);
String s2c = XmlWhitespace.collapse(s2);
return (s1c.equals(s2c));
}
}