1

我正在使用 org.jdom.input.SAXBuilder 将输入流(XML 文件)解析为 JDOM 文档。

SAXBuilder builder = new SAXBuilder(JavaScriptParser.class.getName());
org.jdom.Document document = builder.build(stream);

我的 XML 流中有特定的标签,其标签内的内容必须被视为 CDATA。

例子:

<text><![CDATA[ Any text... ]]></text>
<javascript><![CDATA[ function doSomething(){} ]]></javascript>

目前上面的例子将被解析。我这两天一直在尝试做的是尝试扩展 org.apache.xerces.impl.XMLScanner,以便以下示例解析与上面相同。

例子:

<text>Any text...</text>
<javascript>function doSomething(){}</javascript>

以下是我目前拥有的。scanCDATASection()是从父实现复制的,仅fEntityScanner.scanData("</javascript>", fStringBuffer)更改了行以查找我的结束标记而不是双右括号。我很难确定问题出在哪里,但我认为EntityScanner.scanData("</javascript>")它无法正常工作,因为我从未进入“if”语句。或者我要向scanCDATASection()inside 注入调用的方式scanContent()会导致问题。我不得不想象有一种更清洁、更直接的方法来完成这项任务。我没有定制 XML Parser 的经验,并且在我们的应用程序中每次使用 SAXParser 都使用默认设置。任何建议/提示将不胜感激。

public class JavaScriptScanner extends org.apache.xerces.impl.XMLNSDocumentScannerImpl
{
    private final XMLStringBuffer fStringBuffer = new XMLStringBuffer();

    public JavaScriptScanner()
    {
        super();
    }

    @Override
    protected int scanContent() throws IOException, XNIException 
    {
        if ("javascript".equals(fCurrentElement.rawname))
        {
            scanCDATASection();
            setScannerState(SCANNER_STATE_CONTENT);
        }

        return super.scanContent();
    }

    protected boolean scanCDATASection() throws IOException, XNIException 
    {
        // call handler
        if (fDocumentHandler != null) {
            fDocumentHandler.startCDATA(null);
        }

        while (true) {
            fStringBuffer.clear();
            if (!fEntityScanner.scanData("</javascript>", fStringBuffer) || 
                    fStringBuffer.toString().contains("</javascript")) {
                if (fDocumentHandler != null && fStringBuffer.length > 0) {
                    fDocumentHandler.characters(fStringBuffer, null);
                }
                int brackets = 0;
                while (fEntityScanner.skipChar(']')) {
                    brackets++;
                }
                if (fDocumentHandler != null && brackets > 0) {
                    fStringBuffer.clear();
                    if (brackets > XMLEntityManager.DEFAULT_BUFFER_SIZE) {
                        // Handle large sequences of ']'
                        int chunks = brackets / XMLEntityManager.DEFAULT_BUFFER_SIZE;
                        int remainder = brackets % XMLEntityManager.DEFAULT_BUFFER_SIZE;
                        for (int i = 0; i < XMLEntityManager.DEFAULT_BUFFER_SIZE; i++) {
                            fStringBuffer.append(']');
                        }
                        for (int i = 0; i < chunks; i++) {
                            fDocumentHandler.characters(fStringBuffer, null);
                        }
                        if (remainder != 0) {
                            fStringBuffer.length = remainder;
                            fDocumentHandler.characters(fStringBuffer, null);
                        }
                    }
                    else {
                        for (int i = 0; i < brackets; i++) {
                            fStringBuffer.append(']');
                        }
                       fDocumentHandler.characters(fStringBuffer, null);
                    }
                }
                if (fEntityScanner.skipChar('>')) {
                    break;
                }
                if (fDocumentHandler != null) {
                    fStringBuffer.clear();
                    fStringBuffer.append("]]");
                    fDocumentHandler.characters(fStringBuffer, null);
                }
            }
            else {
                if (fDocumentHandler != null) {
                    fDocumentHandler.characters(fStringBuffer, null);
                }
                int c = fEntityScanner.peekChar();
                if (c != -1 && isInvalidLiteral(c)) {
                    if (XMLChar.isHighSurrogate(c)) {
                        fStringBuffer.clear();
                        scanSurrogates(fStringBuffer);
                        if (fDocumentHandler != null) {
                            fDocumentHandler.characters(fStringBuffer, null);
                        }
                    }
                    else {
                        reportFatalError("InvalidCharInCDSect",
                                        new Object[]{Integer.toString(c,16)});
                        fEntityScanner.scanChar();
                    }
                }
            }
        }
        fMarkupDepth--;

        // call handler
        if (fDocumentHandler != null) {
            fDocumentHandler.endCDATA(null);
        }

        return true;
    }
}
4

0 回答 0