gpt4 book ai didi

java - 如何在不验证或检查 DTD 的情况下设置系统和公共(public) ID?

转载 作者:数据小太阳 更新时间:2023-10-29 02:25:47 25 4
gpt4 key购买 nike

不确定是我的问题还是 API 的问题,但我无法在没有抛出异常或我尝试设置的东西 (DocType) 的情况下创建 XML 文件未设置。

这是我目前正在做的:

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();
}

但是,这样我得到了一个异常(exception)。我可以使用 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);

但是我的 finalDocumentDocType 将是 null

Setting my own EntityResolver也不会成功:

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>

并将其转化为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ds PUBLIC "-//MBO//DTD artikel-at 1.0//DE" "http://dtd.company.de/dtd-at/artikel.dtd">
<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>

最佳答案

对我来说,如果 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 是必需的。


不过有趣的是:它在显示时设置为已读:

在访问 docType 之前:

enter image description here

访问docType后:

enter image description here


这可以在 Xerces 中使用 property http://apache.org/xml/features/dom/defer-node-expansion 进行控制, 默认情况下 true

关于java - 如何在不验证或检查 DTD 的情况下设置系统和公共(public) ID?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41222663/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com