读取数字代码而不是特殊字符

时间:2013-10-12 08:36:13

标签: java xml database sax

我有一个XML文件供SAX解析器读取,存储到CSV并导入数据库。

在我的XML文件中,有一个名为<author>G&uuml;nther Heinemann</author>的作者 如您所见,XML中的“ü”写为&umml;

是的我需要将作者存储在数据库中。我不能将那个角色存储为“ü”。我需要将其存储为&umml;

但是当我使用SAX解析器从XML读取时,它会继续读作“ü”而不是&umml; 如何将Java存储为&umml;而不是“ü”?

谢谢

3 个答案:

答案 0 :(得分:0)

它可能也很慢,因为可能会读取带有包含的大型HTML DTD。 但是你需要这个,因为不允许使用单个&符号(&)。 HTML DTD定义了数百个HTML实体名称,例如&perc;%)。

DTD可以从 XML目录获取,该HTML URL的脱机本地版本是什么。然后,您可以更改实体。但这太过分了。

可以做的是在解析器中安装自己的 EntityHandler ,依此类推。研究工作相对容易。

最简单的方法是将输入包装在您自己的InputStream / Reader中,比如说BufferedReader用&代替&amp;,这样就可以进行替换。

在XML中:&amp;uuml;而不是&uuml;

line = line.replace("&", "&amp;");
// Undo XML escapes:
String[] xmlTags = { "amp", "lt", "gt", "quot", "apos" };
for (String xmlTag : xmlTags) {
    line = line.replace("&amp;" + xmlTag + ";", "&" + xmlTag + ";");
}

答案 1 :(得分:0)

使用Apache Commons LangStringEscapeUtils实用工具escapeHtml()unescapeHtml()

String plain = StringEscapeUtils.unescapeHtml(htmlSafe);

String htmlSafe = StringEscapeUtils.escapeHtml(plain);

答案 2 :(得分:0)

您可以使用下面代码的修改版本来捕获实体的开头和结尾。执行需要几秒钟,因为解析器必须获取所有HTML latin1实体的声明。当您获得一个不以%开头的实体时,您可以替换acc缓冲区中插入的char。注意预定义的实体,如&amp;

您也可以自动将Sax过滤器用于作业。 (CFR)。回答https://stackoverflow.com/a/5524862/452614。我可能会更新我的答案以提供完整的解决方案。

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.*;
import org.xml.sax.ext.DefaultHandler2;

class MyHandler extends DefaultHandler2 {

    private StringBuilder acc;

    public MyHandler() {
        acc = new StringBuilder();
    }

    @Override
    public void startElement(String uri, String localName, String qName,
            Attributes atts) throws SAXException {
        System.out.printf("startElement. uri:%s, localName:%s, qName:%s\n", uri,     localName, qName);
        acc.setLength(0);
    }

    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        System.out.printf("endElement. uri:%s, localName:%s, qName:%s\n", uri,     localName, qName);
        System.out.printf("Characters accumulated: %s\n", acc.toString());
        acc.setLength(0);
    }

    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        acc.append(ch, start, length);
        System.out.printf("characters. [%s]\n", new String(ch, start, length));
    }

    @Override
    public void startEntity(java.lang.String name)
            throws SAXException {
        System.out.printf("startEntity: %s\n", name);
    }

    @Override
    public void endEntity(java.lang.String name)
            throws SAXException {
        System.out.printf("endEntity: %s\n", name);
    }
}

public class SAXTest1 {

    public static void main(String args[]) throws SAXException,     ParserConfigurationException, UnsupportedEncodingException {
        String s = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE author [\n<    !ELEMENT author (#PCDATA)>\n<!ENTITY % HTMLlat1 PUBLIC \"-//W3C//ENTITIES     Latin 1 for XHTML//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent\">    \n%HTMLlat1;\n]>\n<author>G&uuml;nther Heinemann</author>";
        System.out.println(s);
        InputStream stream = new ByteArrayInputStream(s.getBytes("UTF-8"));

        SAXParserFactory factory = SAXParserFactory.newInstance();
        factory.setValidating(true);
        XMLReader xmlReader = factory.newSAXParser().getXMLReader();

        DefaultHandler2 handler = new MyHandler();
        xmlReader.setContentHandler(handler);
        xmlReader.setProperty(
                "http://xml.org/sax/properties/lexical-handler",
                handler);

        try {
            xmlReader.parse(new InputSource(stream));
        } catch (IOException e) {
            System.err.println("I/O error: " + e.getMessage());
        } catch (SAXException e) {
            System.err.println("Parsing error: " + e.getMessage());
        }
    }
}

程序执行:

$ java SAXTest1
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE author [
<!ELEMENT author (#PCDATA)>
<!ENTITY % HTMLlat1 PUBLIC "-//W3C//ENTITIES Latin 1 for XHTML//EN" "http://www.w3.    org/TR/xhtml1/DTD/xhtml-lat1.ent">
%HTMLlat1;
]>
<author>G&uuml;nther Heinemann</author>
startEntity: %HTMLlat1
endEntity: %HTMLlat1
startElement. uri:, localName:, qName:author
characters. [G]
startEntity: uuml
endEntity: uuml
characters. [ünther Heinemann]
endElement. uri:, localName:, qName:author
Characters accumulated: Günther Heinemann