1

"&&"当 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&&"时它会给我这样的错误,如果我不使用特殊字符而不是它的工作正常。

错误 :

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);
    }

}

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

谢谢

4

3 回答 3

5

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

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

同样适用于:

  • <作为&lt;
  • >作为&gt;

请参阅XML 和 HTML 字符实体引用列表

于 2013-06-06T16:09:44.247 回答
4

XML 有五个特殊字符,它们被 XML 解析器特殊处理:

  1. <标签的开始。
  2. >标签的结尾。
  3. "属性值的开始和结束。
  4. '属性值的替代开始和结束。
  5. &实体的开头(以 结尾;)。

因此,您必须将 ' & ' 字符替换为 ' & ' 或者您可以将其替换为将其附加到等效的 Unicode 十进制 ' & ' 在解析它之前。请查看以下示例以更好地理解:

首先,我们可以创建一个模型来表示 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 解析器,如下所示:

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

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

于 2013-06-06T19:09:28.520 回答
0

您需要将其转义为 &

于 2013-06-06T16:13:11.200 回答