Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SAX处理特殊字符_Java_Sax - Fatal编程技术网

Java SAX处理特殊字符

Java SAX处理特殊字符,java,sax,Java,Sax,我试图用Java和SAX为android设备解析一个XML文件。我是从互联网上得到的,在解析它时,我得到了一个例外:字符“é”上的格式不正确(无效标记)。 有没有一种方法可以处理这些字符而不必更改xml文件中的所有特殊字符 编辑: 下面是我将文件写入SD卡的代码部分 File SDCardRoot = Environment.getExternalStorageDirectory(); File f = new File(SDCardRoot,"edt.xml");

我试图用Java和SAX为android设备解析一个XML文件。我是从互联网上得到的,在解析它时,我得到了一个例外:字符“é”上的格式不正确(无效标记)。 有没有一种方法可以处理这些字符而不必更改xml文件中的所有特殊字符

编辑: 下面是我将文件写入SD卡的代码部分

File SDCardRoot = Environment.getExternalStorageDirectory();
            File f = new File(SDCardRoot,"edt.xml");
            f.createNewFile();
            FileOutputStream fileOutput = new FileOutputStream(f);
            InputStream inputStream = urlConnection.getInputStream();


            byte[] buffer = new byte[1024];
            int bufferLength = 0;
            while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
                fileOutput.write(buffer, 0, bufferLength);
            }

            fileOutput.close();
以下是我的xml的一部分:

<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="ttss.xsl"?>

<timetable>
<option combined="0" totalweeks="0" showemptydays="0" dayclass="reverse">
<link href="g56065.xml" class="xml">Imprimer</link>
<link href="g56065.pdf" class="pdf">Version PDF</link>
<weeks>Semaines</weeks>
<dates>Dates</dates>
<week>Semaine</week>
<date>Date</date>
<all>Toutes les semaines</all>
<notes>Remarques</notes>
<id>ID</id>
<tag>Champs Libre</tag>
<footer>Publié le 10/09/2011 22:14:28</footer>
... </timetable>

冒充者
PDF版本
塞曼
日期
塞曼
日期
塞马涅斯酒店
雷马克
身份证件
自由冠军
Publiéle 10/09/2011 22:14:28
... 
以下是解析代码:

public class ParserSemaines extends DefaultHandler {
    private final String SEMAINE = "span";
    private final String DESCRIPTION = "description";
    private ArrayList<Semaine> semaines;
    private boolean inSemaine;
    private Semaine currentSemaine;
    private StringBuffer buffer;
    @Override
    public void processingInstruction(String target, String data) throws SAXException {
        super.processingInstruction(target, data);
    }
    public ParserSemaines() {
        super();
    }

    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        semaines = new ArrayList<Semaine>();
    }

    @Override
    public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
        buffer = new StringBuffer();
        if (localName.equalsIgnoreCase(SEMAINE)){
            this.currentSemaine = new Semaine();
            this.currentSemaine.setDate(attributes.getValue("date"));
            this.inSemaine = true;
        }
        if(localName.equalsIgnoreCase(DESCRIPTION)){
            this.currentSemaine.setDescription(buffer.toString());
        }
    }

    @Override
    public void endElement(String uri, String localName, String name) throws SAXException {
        if (localName.equalsIgnoreCase(SEMAINE)){
            this.semaines.add(currentSemaine);
            this.inSemaine = false;
        }
    }

    public void characters(char[] ch,int start, int length) throws SAXException{
        String lecture = new String(ch,start,length);
        if(buffer != null) buffer.append(lecture);
    }

    public ArrayList<Semaine> getData(){
        return semaines;
    }
}
公共类ParserMaines扩展了DefaultHandler{
私有最终字符串SEMAINE=“span”;
私有最终字符串DESCRIPTION=“DESCRIPTION”;
私有数组列表语义;
私有布尔内因;
私有语义当前语义;
私有字符串缓冲区;
@凌驾
public void processingInstruction(字符串目标、字符串数据)引发SAXException{
超级处理指令(目标、数据);
}
公共parsermaines(){
超级();
}
@凌驾
public void startDocument()引发异常{
super.startDocument();
semaines=newarraylist();
}
@凌驾
public void startElement(字符串uri、字符串localName、字符串名称、属性)引发SAXException{
buffer=新的StringBuffer();
if(localName.equalsIgnoreCase(SEMAINE)){
this.currentSemaine=new Semaine();
this.currentSemaine.setDate(attributes.getValue(“日期”);
this.inSemaine=true;
}
if(localName.equalsIgnoreCase(说明)){
this.currentSemaine.setDescription(buffer.toString());
}
}
@凌驾
公共void endElement(字符串uri、字符串localName、字符串名称)引发SAXException{
if(localName.equalsIgnoreCase(SEMAINE)){
this.semaines.add(currentSemaine);
this.inSemaine=false;
}
}
公共无效字符(char[]ch,int start,int length)引发异常{
字符串讲座=新字符串(ch、开始、长度);
if(buffer!=null)buffer.append(讲座);
}
公共ArrayList getData(){
返回语义;
}
}
下面是我用来调用解析器的代码:

SAXParserFactory fabrique = SAXParserFactory.newInstance();
        SAXParser parseur = null;
        ArrayList<Semaine> semaines = null;
        try {
            parseur = fabrique.newSAXParser();
            DefaultHandler handler = new ParserSemaines();
            File f = new File(Environment.getExternalStorageDirectory(),"edt.xml");
            parseur.parse(f, handler);  
            semaines = ((ParserSemaines) handler).getData();
        }
SAXParserFactory fabrique=SAXParserFactory.newInstance();
SAXParser parseur=null;
ArrayList semaines=null;
试一试{
parseur=fabrique.newSAXParser();
DefaultHandler=new parserMaines();
文件f=新文件(Environment.getExternalStorageDirectory(),“edt.xml”);
parse(f,handler);
语义=((ParserMaines)处理程序).getData();
}
询问是否需要任何其他代码部分

检查后,SD卡中的xml文件似乎将“é”显示为“ëë½”。 这应该是问题所在,但我不知道为什么。
我还尝试用URI进行解析,但它不会改变任何东西,我得到的总是相同的异常。

可能是编码有问题。尝试将其更改为
ISO-8859-1

在xml中,请尝试:

<?xml version="1.0" encoding="ISO-8859-1"?>
检查后,SD卡中的xml文件似乎将“é”显示为“ëë½”

这确实表明存在编码问题

您发布的代码似乎是从URL到文件的正确逐字节副本,因此文件应该准确地表示您从URL获得的内容。这意味着服务器的响应可能不在ISO-8859-1中

我的下一步是使用一个工具,例如检查整个响应,特别注意:

  • 内容类型标题。如果它告诉您一个不同的字符集,您必须将该信息传递给解析器和/或手动转换它
  • 返回的实际字节数。众所周知,内容类型和XML序言都可能是谎言。如果文件是真正的ISO-8859-1,则重音e的字节值应为0xE9。如果内容实际上是UTF-8,则应该有两个字节的序列0xC3 0xA9(请参阅)。您正在显示一个三字节的序列,这没有意义。但最好检查来源
另外,在将文件传递给SAX解析器之前,请确认您没有将其转换为字符串


供参考:我编写了一个连接到OP的URL的最小程序,并将该连接直接传递给最小SAX解析器。它似乎运行正常。我还使用了DOM解析器,并验证了至少根元素已被正确解析

public static void main(String[] argv)
throws Exception
{
   URL url = new URL("http://www.disvu.u-bordeaux1.fr/et/edt_etudiants2/Master/Semestre1/g56065.xml");
   InputStream in = url.openConnection().getInputStream();

   SAXParserFactory spf = SAXParserFactory.newInstance();
   SAXParser parser = spf.newSAXParser();
   parser.parse(in, new DefaultHandler());
   System.out.println("parse successful");
}

我终于找到了解决办法。 我没有使用SAXparder,而是使用

android.util.Xml.parse(InputStream,Xml.Encoding.ISO_8859_1, DefaultHandler);

感谢大家为我提供的帮助。

SAX解析器应该可以毫无问题地处理非ASCII字符。显示您的代码和XML示例。XML文件编码不正确,或为2。XML文件在Internet上的服务是正确的,其字符编码由HTTP头表示,在本地保存该文件时,您会丢失该信息。显示的代码只是将数据复制为原始字节,因此不能以任何方式混淆XML编码。您需要显示解析代码。请在设置实际SAX解析器的位置添加代码(即,从解析器工厂获取解析器并调用parse())。解析代码看起来很好,这表明服务器提供的内容不正确。在“我的xml”中,编码设置正确。我从不使用inputSource,我应该在哪里使用它?这是fiddler结果,响应头:HTTP/1.0 200 OK Date:Wed,2011年9月14日16:01:44 GMT服务器:Apache上次修改:Wed,2011年9月14日15:18:40 GMT ETag:“da80c9-1e634-46611400”接受范围:字节内容长度:124468连接:关闭内容类型:我选中的应用程序/xml和“é”十六进制结果中的有效值为0xE9。我觉得我得到的唯一解决办法就是把所有的“e”改成“e”
android.util.Xml.parse(InputStream,Xml.Encoding.ISO_8859_1, DefaultHandler);