0

我正在像这样在 JAVA 中读取 XML 文件:

String filepath = xmlFile;
File workFile = new File(filepath);
File fragmentDir = workFile.getParentFile();
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepath);

在这个 xml 文件中有像 &testRef; 这样的引用。

我有另一个文件,我在其中声明了所有这样的实体:

<!ENTITY testRef 'hello"'>

简单的解决方案是直接在 xml 文件中添加这些引用或添加一个!ENTITY 系统“file.ref”,但我不能。有没有可以告诉我的 DocumentBuilderFactory 的解决方案:使用此文件来阅读参考资料?

编辑:我试过这个:

docBuilder.setEntityResolver(new EntityResolver() {
            public InputSource resolveEntity(String publicId, String systemId) throws SAXException,IOException {
                System.out.println("Resolving");
                return new InputSource("file.ref");
            }
        });

但是我不断收到“引用了实体“testRef”,但没有声明......”,甚至没有打印文本“Resolving”。似乎文档构建器没有考虑到新的解析器。

我错过了什么?

4

2 回答 2

1

使用DocumentBuilder'ssetEntityResolver方法。

class Resolver implements EntityResolver {

  public InputSource resolveEntity(String publicId, String systemId) {
  if (systemId.equals("THE_SYSTEM_ID_THAT_YOU_ARE_USING")) {
     System.out.println("Resolving Entity...");
     return new InputSource("YOUR_REFERENCES_XML");
  } else {
     // use the default behaviour
     return null;
  }
  }
}

进而

DocumentBuilder builder = factory.newDocumentBuilder();
Resolver res = new Resolver();
builder.setEntityResolver(res);
Document doc = builder.parse("YOUR XML FILE");

编辑:

在深入了解 EntityResolver 之后,我发现如果 XML 文件未声明实体引用文件(这是您手头的问题),实体解析器将被忽略。但是,您可以调整以下技巧以使其工作:

static String template =
           "<!DOCTYPE x [ "
         + "<!ENTITY  % entities SYSTEM \"{0}\"> "
         + "<!ENTITY file SYSTEM \"{1}\" >" + "%entities;" + "]>"
         + "<x>&file;</x>";

 private static String createFromTemplate(File entityFile, File xmlFile) {
     return MessageFormat.format(template, entityFile.getAbsolutePath(),
             xmlFile.getAbsolutePath());
 }

 private static File entityFile = new File(<ENTITYFILE>);

 public Document parse(File f) throws JDOMException, IOException {
     String xml = createFromTemplate(entityFile, f);
     SAXBuilder builder = new SAXBuilder();
     Document doc = builder.build(new StringReader(xml));
     Element e = (Element) doc.getRootElement().getChildren().get(0);
     e.detach();
     Document doc2 = new Document(e);
     return doc2;
 }

ENTITYFILE 是声明实体引用的文件。

希望有帮助。

于 2013-06-12T14:20:59.257 回答
0
public static void main(String[] args) {

    try {

        System.out.println("Start Process");
        File xmlFile = new File("/Users/cgonzalez/Desktop/test.xml");
        SAXBuilder builder = new SAXBuilder();
        Document document = new Document();
        document = builder.build(xmlFile);

        HashMap piMap = new HashMap(2);
        piMap.put("type", "text/xsl");
        piMap.put("href", "http://localhost:8080/achs-expdf-web/app/resource/xslt/plantilla.xsl");
        ProcessingInstruction pi = new ProcessingInstruction("xml-stylesheet", piMap);

        document.getContent().add(0, pi);

        // new XMLOutputter().output(doc, System.out);
        XMLOutputter xmlOutput = new XMLOutputter();

        // display nice nice
        xmlOutput.setFormat(Format.getPrettyFormat());
        xmlOutput.output(document, new FileWriter("/Users/cgonzalez/Desktop/test.xml"));
        System.out.println("end Process");
    } catch (Exception e) {
        e.printStackTrace();
    }
}
于 2016-04-27T20:53:54.747 回答