我使用Java的项目需要基于抽象表示输出XML,该抽象表示被建模为自己的类/数据类型。考虑到这个功能
public static String renderToString(Node element) {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = null;
try {
transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
} catch (TransformerConfigurationException e) {
e.printStackTrace();
}
DOMSource source = new DOMSource(element);
StreamResult result = new StreamResult(new StringWriter());
try {
transformer.transform(source, result);
} catch (TransformerException e) {
e.printStackTrace();
}
return result.getWriter().toString();
}
我编写了一个测试,构造一个等价的元素
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="8000" COLLATION="SQL_Latin1_General_CP1_CI_AS" />
这由以下函数生成
public static Element createFieldElement(Document doc) {
Element fieldElement = doc.createElement("FIELD");
...
fieldElement.setAttribute("xsi:type", "CharTerm");
return fieldElement;
}
将此元素传递给函数我现在得到一个错误,告诉我缺少'xsi'命名空间(与xsi:type属性一起使用),这是有道理的,因为我尝试渲染的元素不是完整的XML文档。
我是否必须设置一个选项或以任何方式绕过XML Namespace声明以保持我的代码可测试?
否则我会尝试模拟一些函数来欺骗Transformer无论如何都要渲染Element,但我不会建议一个方便的选项。
最终我发现无法省略命名空间检查,但为了测试,我发现了在测试时添加命名空间的折衷方案。
@Test
public void IfColumnDescriptionGivenThenGenerateAccordingField() {
Element element = XSDCreator.createFieldElement(doc, 1, ";");
element.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
String output = XSDCreator.renderToString(element);
assertEquals(output, "Here comes the output");
}
这可能不是真正的输出,但这应该足以用于测试目的。另一种方法是使用适当的名称空间声明生成Document并呈现整个文档。