【问题标题】:SAX Parser characters method doesn't collect all contentSAX 解析器字符方法不收集所有内容
【发布时间】:2015-07-22 16:29:49
【问题描述】:

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

我在 XML 中有以下标记。

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

在这里,我希望 '•CERTASS >> Certass' 作为输出。但下面的代码只返回Certassvalue标签的特殊字符有什么问题吗?

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

【问题讨论】:

    标签: java xml sax


    【解决方案1】:

    不保证characters() 方法在元素内只运行一次

    如果您将内容存储在String 中,而characters() 方法恰好运行了两次,您将只能从第二次运行中获取内容。 characters 方法第二次运行时会覆盖第一次存储的 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 "&lt;value&gt;•CERTASS &gt;&gt; Certass&lt;/value&gt;" 和上面的处理程序给出输出:

    ?CERTASS >> Certass
    

    我希望这会有所帮助。

    【讨论】:

    • 感谢您的回答。我有 wuch >> 这样的 PassPlus,>> Pass Plus,。这个逻辑会处理吗?另外,我可以使用 DOM 解析器来避免此类问题吗?
    • 实际上 DOM 解析器甚至不会让您解析带有未转义特殊字符的文档。我很高兴能帮上忙。
    【解决方案2】:

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

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

    还要小心值内的换行符/换行符!!! 如果 xml 在没有您控制的情况下被换行,则还将为语句中的每一行调用 characters 方法,并且它将返回换行符! (您需要依次手动剥离)。

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

     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 = "";
         }
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多