XML文件节点属性在具有特殊字符时未解析

时间:2013-06-06 16:05:14

标签: java android xml-parsing sax

XML文件在节点的属性值中包含"&&"时无法解析。

XML文件:

<?xml version="1.0" encoding="UTF-8" ?>
<test version="0.0.3" >
    <SFTP ipaddress="12.12.12.12" port="22" uname="abc" pwd="abc&&" path="/testdev" />
</test>

当使用 pwd =“abc&amp;&amp;”时,它会给我这样的错误,如果我不会使用特殊字符而不是它的工作正常。

错误:

At line 3, column 62: not well-formed (invalid token)
    org.apache.harmony.xml.ExpatParser$ParseException: At line 3, column 62: not well-formed (invalid token)
    at org.apache.harmony.xml.ExpatParser.parseFragment(ExpatParser.java:515)
    at org.apache.harmony.xml.ExpatParser.parseDocument(ExpatParser.java:474)
    at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:321)
    at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:279)
    at com.test.bl.ConfigurationParser.parseFile(ConfigurationParser.java:61)
    at com.test.ui.LoginActivity$ConfigurationXMLParseOperation.doInBackground(LoginActivity.java:209)
    at com.test.ui.LoginActivity$ConfigurationXMLParseOperation.doInBackground(LoginActivity.java:1)
    at android.os.AsyncTask$2.call(AsyncTask.java:287)
    at java.util.concurrent.FutureTask.run(FutureTask.java:234)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
    at java.lang.Thread.run(Thread.java:856)

代码:

public void parseFile(final InputStream inputStream) throws ParserConfigurationException,
        SAXException, IOException {
    try {
        final SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        final SAXParser saxParser = saxParserFactory.newSAXParser();
        final XMLReader xmlReader = saxParser.getXMLReader();
        xmlReader.setContentHandler(this);
        xmlReader.parse(new InputSource(inputStream));
    } catch (ParserConfigurationException e) {
        Logger.e(TAG, e.getMessage(), e);
    } catch (SAXException e) {
        Logger.e(TAG, e.getMessage(), e);
    } catch (IOException e) {
        Logger.e(TAG, e.getMessage(), e);
    }
}


@Override
public void startElement(final String uri, final String localName, final String qName,
        final Attributes attributes) throws SAXException {
    mElementStart = true;
    if (localName.equals(null)) {
        Logger.i(TAG, "Devices xml file is empty");
    }
    tempValue = "";
    if (localName.equalsIgnoreCase(mSFTPParseNodeString)) {
        sftpConfiguration = new SFTPConfiguration();

        sftpConfiguration.mSftpIp = attributes.getValue(mSFTPIpParseNodeString);

        sftpConfiguration.mRemotePath = attributes.getValue(mSFTPPathParseNodeString);

        sftpConfiguration.mSftpPort = Integer.parseInt(attributes
                .getValue(mSFTPPortParseNodeString));

        sftpConfiguration.mUserName = attributes.getValue(mSFTPUserNameParseNodeString);

        sftpConfiguration.mUserPassword = attributes.getValue(mSFTPPasswordParseNodeString);
    }

}

请帮助我并给我解决方案如何解析此值并在我的代码中使用。

由于

3 个答案:

答案 0 :(得分:5)

在XML中,所有&个字符必须编码为&amp;

因此,无论文件来自何处,您都必须在尝试解析XML之前更改这些字符。

同样的:

  • <&lt;
  • >&gt;

请参阅List of XML and HTML character entity references

答案 1 :(得分:4)

XML有五个特殊字符,由XML解析器进行特殊处理:

  1. &lt; 标签的开头。
  2. &gt; 标记的结尾。
  3. 属性值的开头和结尾。
  4. '属性值的替代开头和结尾。
  5. &amp; 实体的开头(以;结尾)。
  6. 因此,您必须将“&amp; ”字符替换为“&amp; amp; ”,否则您可以将其替换为将其附加到Unicode十进制等效值'解析之前&amp;#38; '。请查看以下示例以便更好地理解:

    首先,我们可以创建一个Model来表示XML文件中的数据:

    package com.stackoverflow.xml.parser.service;
    
    /**
     * @author sarath_sivan
     */
    public class SFTPConfiguration {
    
        private String ipAddress;
        private int port;
        private String userName;
        private String password;
        private String path;
    
        public SFTPConfiguration() {}
    
        public SFTPConfiguration(String ipAddress, int port, 
                String userName, String password, String path) {
            this.ipAddress = ipAddress;
            this.port = port;
            this.userName = userName;
            this.password = password;
            this.path = path;
        }
    
        public String getIpAddress() {
            return ipAddress;
        }
    
        public void setIpAddress(String ipAddress) {
            this.ipAddress = ipAddress;
        }
    
        public int getPort() {
            return port;
        }
    
        public void setPort(int port) {
            this.port = port;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public String getPath() {
            return path;
        }
    
        public void setPath(String path) {
            this.path = path;
        }
    
        public String toString() {
            StringBuffer sftpConfigBuilder = new StringBuffer();
            sftpConfigBuilder.append("SFTP Configuration Details > ");
            sftpConfigBuilder.append("IP Address: ").append(getIpAddress()).append(", ");
            sftpConfigBuilder.append("Port: ").append(getPort()).append(", ");
            sftpConfigBuilder.append("UserName: ").append(getUserName()).append(", ");
            sftpConfigBuilder.append("Password: ").append(getPassword()).append(", ");
            sftpConfigBuilder.append("Path: ").append(getPath());
            return sftpConfigBuilder.toString();
        }
    
    }
    

    现在,您可以实现SAX Parser,如下所示:

    package com.stackoverflow.xml.parser.service;
    
    import java.io.ByteArrayInputStream;
    import java.io.File;
    import java.io.IOException;
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.parsers.SAXParser;
    import javax.xml.parsers.SAXParserFactory;
    
    import org.apache.commons.io.FileUtils;
    import org.xml.sax.Attributes;
    import org.xml.sax.SAXException;
    import org.xml.sax.helpers.DefaultHandler;
    
    /**
     * @author sarath_sivan
     */
    public class SFTPConfigHandler extends DefaultHandler {
    
        private SFTPConfiguration sftpConfiguration;
        private String configData;
    
        public void characters(char[] buffer, int start, int length) {
            configData = new String(buffer, start, length);
        }
    
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            configData = "";
            if (qName.equalsIgnoreCase("SFTP")) {
                sftpConfiguration = new SFTPConfiguration();
                sftpConfiguration.setIpAddress(attributes.getValue("ipaddress"));
                sftpConfiguration.setPort(Integer.parseInt(attributes.getValue("port")));
                sftpConfiguration.setUserName(attributes.getValue("uname"));
                sftpConfiguration.setPassword(attributes.getValue("pwd"));
                sftpConfiguration.setPath(attributes.getValue("path"));
            }
        }
    
        public void endElement(String uri, String localName, String qName)
                throws SAXException {
            //do something if required.
        }
    
        public SFTPConfiguration getSFTPConfiguration() {
            return sftpConfiguration;
        }
    
        public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
            SAXParserFactory saxParserFactory  = SAXParserFactory.newInstance();
            SAXParser saxParser  = saxParserFactory.newSAXParser();
            SFTPConfigHandler sftpConfigHandler = new SFTPConfigHandler();
            String strXml = FileUtils.readFileToString(new File("C:/Users/sarath_sivan/Desktop/sftp-config.xml"));
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(strXml.replaceAll("&", "&amp;").getBytes("UTF-8"));
            saxParser.parse(byteArrayInputStream, sftpConfigHandler);
            System.out.println(sftpConfigHandler.getSFTPConfiguration().toString());
        }
    }
    

    <强>输出:

    SFTP Configuration Details > IP Address: 12.12.12.12, Port: 22, UserName: abc, Password: abc&&, Path: /quipmentdev
    

    希望这会有所帮助...... 谢谢!

答案 2 :(得分:0)

您需要将其作为&amp; amp

转义