如何使用DOM来转义特殊字符

Und*_*007 5 java xml dom domdocument xml-parsing

这个问题最近一直困扰着我,我似乎无法找到一个可能的解决方案.

我正在处理一个Web服务器,它接收一个XML文档来进行一些处理.服务器的解析器与&,',",<,>有问题.我知道这很糟糕,我没有在该服务器上实现xml解析器.但在等待补丁之前我需要规避.

现在,在将我的XML文档上传到此服务器之前,我需要解析它并转义xml特殊字符.我目前正在使用DOM.问题是,如果我遍历TEXT_NODES并用转义版本替换所有特殊字符,当我保存此文档时,

因为d'ex我得到d&amp;apos;ex 但我需要d&apos;ex

这是有道理的,因为DOM逃脱了"&".但显然这不是我需要的.

所以,如果DOM已经能够逃逸"&""&amp;"我怎样才能使它逃避其他人物像"&quot;

如果它不能,我怎样才能保存已解析和转义的文本在它的节点中,而不必在保存时重新转义它们?

这是我如何逃避我使用apache StringEscapeUtils类的特殊字符:

public String xMLTransform() throws Exception
      {

         String xmlfile = FileUtils.readFileToString(new File(filepath));

         DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
         Document doc = docBuilder.parse(new InputSource(new StringReader(xmlfile.trim().replaceFirst("^([\\W]+)<", "<"))));

       NodeList nodeList = doc.getElementsByTagName("*");

       for (int i = 0; i < nodeList.getLength(); i++) {
          Node currentNode = nodeList.item(i);
          if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
              Node child = currentNode.getFirstChild();
              while(child != null) {
                  if (child.getNodeType() == Node.TEXT_NODE) {                   
                    child.setNodeValue(StringEscapeUtils.escapeXml10(child.getNodeValue()));
//Escaping works here. But when saving the final document, the "&" used in escaping gets escaped as well by DOM.


                  }
                  child = child.getNextSibling();
              }
          }
      }

         TransformerFactory transformerFactory = TransformerFactory.newInstance();

       Transformer transformer = transformerFactory.newTransformer();
         DOMSource source = new DOMSource(doc);
         StringWriter writer = new StringWriter();
         StreamResult result = new StreamResult(writer);
         transformer.transform(source, result);


         FileOutputStream fop = null;
         File file;

         file = File.createTempFile("escapedXML"+UUID.randomUUID(), ".xml");

         fop = new FileOutputStream(file);

         String xmlString = writer.toString();
         byte[] contentInBytes = xmlString.getBytes();

         fop.write(contentInBytes);
         fop.flush();
         fop.close();

      return file.getPath();


      }
Run Code Online (Sandbox Code Playgroud)

小智 1

我见过人们使用正则表达式来做类似的事情

复制自(用 Java 中特殊字符前面的转义符替换特殊字符

String newSearch = search.replaceAll("(?=[]\\[+&|!(){}^\"~*?:\\\\-])", "\\\\");

这个奇怪的正则表达式是一个“前瞻” - 一个非捕获断言,以下字符匹配某些内容 - 在本例中是一个字符类。

请注意,除了 ] 之外,您不需要转义字符类中的字符(即使是减号,如果第一个或最后一个也不需要转义)。

\\\\就是编写正则表达式文字的方式 \ (对于 java 转义一次,对于正则表达式转义一次)

这是对此工作的测试:

public static void main(String[] args) { String search = "code:xy"; String newSearch = search.replaceAll("(?=[]\\[+&|!(){}^\"~*?:\\\\-])", "\\\\"); System.out.println(newSearch); }

输出:

code\:xy