SAX 解析器字符方法不收集所有内容

SAX Parser characters method doesn't collect all content

我正在使用 SAX 解析器解析 XML 并且工作正常。

我在 XML 中有以下标签。

<value>•CERTASS >> Certass</value>

这里我期望'•CERTASS >> Certass'作为输出。但下面的代码 returns 仅 Certassvalue 标签的特殊字符有问题吗?

public void characters(char[] buffer, int start, int length) {
           temp = new String(buffer, start, length);
    }

不能保证 characters() 方法在一个元素 中只会 运行 一次。

如果你将内容存储在String中,而characters()方法恰好运行两次,你只会从第二次运行中获取内容.字符方法 运行s 第二次将覆盖第一次存储的 temp 变量的内容。

要解决这个问题,请使用 StringBuilderappend() characters() 中的内容,然后处理 endElement() 中的内容。例如:

 DefaultHandler handler = new DefaultHandler() {
     private StringBuilder stringBuilder;

     @Override
     public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
         stringBuilder = new StringBuilder();
     }

     public void characters(char[] buffer, int start, int length) {
         stringBuilder.append(new String(buffer, start, length));
     }

     public void endElement(String uri, String localName, String qName) throws SAXException {
         System.out.println(stringBuilder.toString());
     }
 };

解析 String<value>•CERTASS >> Certass</value>” 和上面的处理程序给出输出:

?CERTASS >> Certass

希望对您有所帮助。

前几天我 运行 遇到了这个问题,事实证明这是因为 CCharacters 方法被多次调用,以防这些字符中的任何一个包含在值中:

"   &quot;
'   &apos;
<   &lt;
>   &gt;
&   &amp;

还要注意值内的换行符/换行符!!! 如果 xml 在没有您控制的情况下换行,字符方法也将为语句中的每一行调用,另外它将 return 换行! (需要手动依次去掉)

处理所有这些问题的示例处理程序是这个:

 DefaultHandler handler = new DefaultHandler() {
   private boolean isInANameTag = false;
   private String localname;
   private StringBuilder elementContent;

   @Override
   public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException {
    if (qname.equalsIgnoreCase("myfield")) {
      isInMyTag = true;
      this.localname = localname;
      this.elementContent = new StringBuilder();
    }
   }

   public void characters(char[] buffer, int start, int length) {
      if (isInMyTag) {
         String content = new String(ch, start, length);
         if (StringUtils.equals(content.substring(0, 1), "\n")) {
              // remove leading newline
              elementContent.append(content.substring(1));
         } else {
              elementContent.append(content);
         }
      }
   }

   public void endElement(String uri, String localName, String qName) throws SAXException {
     if (qname.equalsIgnoreCase("myfield")) {
       isInMyTag = false;
       // do something with elementContent.toString());
       System.out.println(elementContent.toString());
       this.localname = "";
     }
   }
}