【问题标题】:Parse value containing special character "/" gives wrong output using SAX parser使用 SAX 解析器解析包含特殊字符“/”的值会给出错误的输出
【发布时间】:2017-11-24 05:48:10
【问题描述】:

我有下面的xml结构

  <fs:AsReportedItem>
     <fs:BookMark>/BODY[1]/DIV[3135]/DIV[0]/TABLE[0]/TBODY[0]/TR[32]/TD[5]/DIV[0]/FONT[0]/substr(1,2)
     </fs:BookMark>
  </fs:AsReportedItem>

我正在使用 SAX 解析并在 endElement() 方法中读取税值

这是我的示例代码

private void parseDocument() {
        // parse
        SAXParserFactory factory = SAXParserFactory.newInstance();
        try {
            SAXParser parser = factory.newSAXParser();
            parser.parse(FileName, this);
        } catch (ParserConfigurationException e) {
            System.out.println("ParserConfig error");
        } catch (SAXException e) {
            System.out.println("SAXException : xml not well formed");
        } catch (IOException e) {
            System.out.println("IO error");
        }
    }

public void startElement(String s, String s1, String elementName, Attributes attributes) throws SAXException {

if (OrgDataPartitonObj != null && "fs:FinancialStatementLineItemDataItem".equals(OrgDataPartitonObj.getType())) {

                FinancialStatementLineItemParser.startFinancialStatementLineItemParser(OrgDataPartitonObj,financialStatementLineItemObj, elementName, attributes);

            }
        }


public void endElement(String s, String s1, String element) throws SAXException {

if (OrgDataPartitonObj != null && "fs:FinancialStatementLineItemDataItem".equals(OrgDataPartitonObj.getType())) {

                 FinancialStatementLineItemParser.getEndElementFinancialStatementLineItemParser(financialStatementLineItemObj, element, tmpValue);
        }
}


public static void getEndElementFinancialStatementLineItemParser(FinancialStatementLineItem financialStatementLineItemObj, String element, String tmpValue) {

            if (element.equals("fs:BookMark")) {
            financialStatementLineItemObj.setBookMark(tmpValue);
        }

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

当我调试时,我只能看到这个值/substr(1,2) 所有带有"/" 的值都被转义了

我不知道为什么我没有获得全部价值/BODY[1]/DIV[3135]/DIV[0]/TABLE[0]/TBODY[0]/TR[32]/TD[5]/DIV[0]/FONT[0]/substr(1,2)

如果使用了任何转义字符,那么我必须在哪里使用。

【问题讨论】:

  • 为什么"/"被转义了?
  • @DevilsHnd 我的问题是什么
  • 与“/”无关。 Sax-DefaultHandler 的 characters() 方法总是返回有限的字符数。要获取全文,您必须收集 characters() 方法的文本。
  • 只是为了扩展@RalfRenz 的答案:SAX 解析器可以分解文本并在多次调用 characters() 时将其移交。它可以在任何它选择的地方拆分文本,但许多解析器发现在实体扩展发生的点拆分它很方便。
  • @MichaelKay 那么您建议进行哪些更改以获得全文

标签: java xml sax saxparser


【解决方案1】:

这里是用于收集文本的 DefaultHandler 的源代码:

private static DefaultHandler getHandler() {
    return new DefaultHandler() {
        String text;

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes)
                throws SAXException {
            if ("BookMark".equals(qName)) {
                text = "";
            }
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            text += new String(ch).trim();
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            if ("BookMark".equals(qName)) {
                System.out.println("endElement: " + text);
            }
        }

    };
}

【讨论】:

  • 它如何解决我的问题。我需要做什么才能获得全文
  • 我获得了价值,但我没有获得text 本身的全部价值
  • 为什么不显示您编写的用于解析 xml 的代码?那么帮助你就更容易了。
【解决方案2】:

您需要将您的 characters() 方法更改为

@Override
public void characters(char[] buffer, int start, int length) {
    tmpValue += new String(buffer, start, length);
}

并且您必须将 startElement() 方法中的 tmpValue 重置为 ""。

【讨论】:

    【解决方案3】:

    只需更改 character() 方法

    @Override
        public void characters(char[] buffer, int start, int length) {
            tmpValue += new String(buffer, start, length);
        }
    

    并将其添加到 endElement 方法的最后一行。

    public void endElement(String s, String s1, String element) throws SAXException {
    
    if (OrgDataPartitonObj != null && "fs:FinancialStatementLineItemDataItem".equals(OrgDataPartitonObj.getType())) {
    
      FinancialStatementLineItemParser.getEndElementFinancialStatementLineItemParser(financialStatementLineItemObj, element, tmpValue);
            }
    tmpValue="";
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-08-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多