不确定它是仅仅是我还是API但是我根本无法创建XML文件而没有抛出异常或者我试图设置(DocType
)没有设置的东西
这就是我目前正在做的事情:
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
stringBuilder.append("<!DOCTYPE document>");
String xmlString = AnnotatedDocumentTree.toString(annotatedDocumentTree, new SimpleAnnotatedDocumentTreeXmlConverter(), stringBuilder);
DocumentBuilderFactory icFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder icBuilder;
Document finalDocument = null;
StringWriter writer = new StringWriter();
try {
icBuilder = icFactory.newDocumentBuilder();
finalDocument = icBuilder.parse(new InputSource(new ByteArrayInputStream(xmlString.getBytes("UTF-8"))));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
DocumentType doctype = xmlDocument.getDoctype();
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doctype.getSystemId());
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, doctype.getPublicId());
transformer.transform(new DOMSource(finalDocument), new StreamResult(writer));
finalDocument = icBuilder.parse(new InputSource(new ByteArrayInputStream(writer.toString().getBytes("UTF-8"))));
} catch (Exception e) {
e.printStackTrace();
}
然而,这样我得到了一个例外。我可以使用DocumentBuilderFactory
并将其配置为this:
icFactory.setValidating(false);
icFactory.setNamespaceAware(true);
icFactory.setFeature("http://xml.org/sax/features/namespaces", false);
icFactory.setFeature("http://xml.org/sax/features/validation", false);
icFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
icFactory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
但我的DocType
的{{1}}将为finalDocument
。
Setting my own EntityResolver
也不会这样做:
null
因为如果我想设置builder.setEntityResolver(new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
if (systemId.contains(".dtd")) {
return new InputSource(new StringReader(""));
} else {
return null;
}
}
});
我 想要设置doctype.getSystemId()
。
有没有办法在没有头痛的情况下推动它?
基本上我想解析一下:
doctype.getSystemId()
并将其转换为:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!DOCTYPE document>
<ds>
ABGB <cue>: §§ 786 , 810 , 812 </cue>Die Kosten der ...
<cue>von</cue>
<Relation bewertung="1">7 Ob 56/10a </Relation>=
<Relation bewertung="1">Zak 2010/773 , 440 </Relation>.
</ds>
答案 0 :(得分:2)
对我来说,如果dtd存在于指定位置(systemId),则代码可以正常工作,否则在代码中添加实体解析器会产生诀窍。
我没有xmlDocument
因此我对值进行了硬编码
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>");
stringBuilder.append("<!DOCTYPE document><document/>");
String xmlString = stringBuilder.toString(); // AnnotatedDocumentTree.toString(annotatedDocumentTree, new SimpleAnnotatedDocumentTreeXmlConverter(), stringBuilder);
DocumentBuilderFactory icFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder icBuilder;
Document finalDocument = null;
StringWriter writer = new StringWriter();
try {
icBuilder = icFactory.newDocumentBuilder();
finalDocument = icBuilder.parse(new InputSource(new ByteArrayInputStream(xmlString.getBytes("UTF-8"))));
Transformer transformer = TransformerFactory.newInstance().newTransformer();
//DocumentType doctype = xmlDocument.getDoctype();
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "xdtd.dtd"); // doctype.getSystemId());
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "xxxx"); //doctype.getPublicId());
transformer.transform(new DOMSource(finalDocument), new StreamResult(writer));
icBuilder.setEntityResolver(new EntityResolver() {
@Override
public InputSource resolveEntity(String publicId, String systemId)
throws SAXException, IOException {
if (systemId.contains(".dtd")) {
return new InputSource(new StringReader(""));
} else {
return null;
}
}
});
finalDocument = icBuilder.parse(new InputSource(new ByteArrayInputStream(writer.toString().getBytes("UTF-8"))));
System.out.println(finalDocument.getDoctype().getPublicId());
System.out.println("-----------");
System.out.println(writer.toString());
} catch (Exception e) {
e.printStackTrace();
}
输出:
xxxx
-----------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE document PUBLIC "xxxx" "xdtd.dtd">
<document/>
在创建构建器之前,还必须在没有实体解析器的情况下设置属性的选项。在这些属性中,只需要http://apache.org/xml/features/nonvalidating/load-external-dtd
。
虽然这是有趣的事情:它会在出现时设置为on-read:
在访问docType
之前:
访问docType
后:
这可以使用property http://apache.org/xml/features/dom/defer-node-expansion
在Xerces中进行控制,默认为true
答案 1 :(得分:2)
试试这个:
Transformer t = TransformerFactory.newInstance().newTransformer();
Source s = new StreamSource(new StringReader(inputXML));
StringWriter sw = new StringWriter();
t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, "my.system.id");
t.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC, "my/public/id");
t.transform(s, new StreamResult(sw));
根本不需要通过DOM。