Android xml数据的读取和写入(sax,pull,dom,xstream,jsoup)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 一、引用1、用XmlSerializer写xml文件与读xml文件2、xml解析(读取xml,保存文件到xml)3、Android-利用Document来对xml进行读取和写入操作4、手把手教学 Android用jsoup解析html文内相关其他XStream解析xml数据1、Android XStream 解析xml数据变成bean,支持CDATA2、Retrofit 用Soap协议访问WebService 详解二、数据格式1、xml数据包含单个数据,列表数据,bean数据。

一、引用

1、用XmlSerializer写xml文件与读xml文件
2、xml解析(读取xml,保存文件到xml)
3、Android-利用Document来对xml进行读取和写入操作
4、手把手教学 Android用jsoup解析html

文内相关其他XStream解析xml数据

1、Android XStream 解析xml数据变成bean,支持CDATA
2、Retrofit 用Soap协议访问WebService 详解

二、数据格式

1、xml数据

包含单个数据,列表数据,bean数据。有tag,attribute,content-text
以下我们就是我们要读取和写入的数据

 * <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
 * <xml_data>
 *      <user name="wujn" />
 *      <deviceinfos>
 *          <deviceinfo id="1">
 *               <name>仪器123</name>
 *               <price>188</price>
 *               <company>YYY</company>
 *               <usage>检测兽药残留</usage>
 *          </deviceinfo>
 *          <deviceinfo id="2">
 *               <name>仪器456</name>
 *               <price>199</price>
 *               <company>XXX</company>
 *               <usage>检测农药残留及多参数</usage>
 *          </deviceinfo>
 *      </deviceinfos>
 * </xml_data>

2、bean

public class DeviceInfo {
    String name;
    int id;
    int price;
    String company;
    String usage;

    public DeviceInfo(){}

    public DeviceInfo(String name,int id,int price,String company,String usage){
        this.name = name;
        this.id = id;
        this.price = price;
        this.company = company;
        this.usage = usage;
    }
     
   //省略get,set,tostring...
}  

三、写入

1、XmlSerializer - xml序列,本质是pull

1.1、设置输出文件流FileOutputStream,xml序列号,文本格式...
1.2、startTag和endTag为一个元素的开始和结束标志
1.3、attribute 是当前tag的属性,一般来说bean的元素都可以放在里面
1.4、text 是tag的content-text,就是文本值
1.5、关闭xml序列文本、关闭FileOutputStream

  /**写入XML数据*/
    private void WriteXmlToSdcardByXmlSerial(){
        List<DeviceInfo> deviceInfoList = new ArrayList<>();
        DeviceInfo deviceInfo = new DeviceInfo("仪器123",1,188,"YYY","检测兽药残留");
        DeviceInfo deviceInfo3 = new DeviceInfo("仪器456",2,199,"XXX","检测农药残留及多参数");
        deviceInfoList.add(deviceInfo);
        deviceInfoList.add(deviceInfo3);

        try {
            //-------内部-----------
//            // 指定流目录
//            OutputStream os = openFileOutput("persons.xml", Context.MODE_PRIVATE);
//            // 设置指定目录
//            serializer.setOutput(os, "UTF-8");

            //--------外部---------
            //xml文件的序列号器  帮助生成一个xml文件
            FileOutputStream fos = new FileOutputStream(new File(xmlPath));

            //获取到xml的序列号
            XmlSerializer serializer = Xml.newSerializer();
            //序列化初始化
            serializer.setOutput(fos, "utf-8");
            //创建xml
            serializer.startDocument("utf-8", true);

            //顶层element有且只有一个
            serializer.startTag(null,"xml_data");

            //tag+attribute:<user name="wujn" />
            //tag+text:<user>wujn</user>
            serializer.startTag(null,"user");
            serializer.attribute(null,"name","wujn");
            //serializer.text("wujn");
            serializer.endTag(null,"user");

            //多组<deviceinfo>...</deviceinfo>
            serializer.startTag(null,"deviceinfos");
            for(int i=0;i<deviceInfoList.size();i++){
                serializer.startTag(null,"deviceinfo");
                serializer.attribute(null,"id",String.valueOf(deviceInfoList.get(i).getId()));

                serializer.startTag(null,"name");
                serializer.text(deviceInfoList.get(i).getName());
                serializer.endTag(null,"name");

                serializer.startTag(null,"price");
                serializer.text(String.valueOf(deviceInfoList.get(i).getPrice()));
                serializer.endTag(null,"price");

                serializer.startTag(null,"company");
                serializer.text(deviceInfoList.get(i).getCompany());
                serializer.endTag(null,"company");

                serializer.startTag(null,"usage");
                serializer.text(deviceInfoList.get(i).getUsage());
                serializer.endTag(null,"usage");

                serializer.endTag(null,"deviceinfo");
            }
            serializer.endTag(null,"deviceinfos");

            //顶层element有且只有一个
            serializer.endTag(null,"xml_data");

            //关闭文档
            serializer.endDocument();
            //写入流关闭
            fos.flush();
            fos.close();

            ToastUtil.showShort(instance,"xml数据已导出");

        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());
        } catch (IllegalStateException e) {
            e.printStackTrace();
            ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());
        }

    }

2、Document - dom形式

1.1、DocumentBuilderFactory工厂新建一个document
1.2、createElement 新建元素,里面放的是tag值
1.3、setAttribute 设置attribute,一般bean类数据可放这里
1.4、setTextContent 是tag的content-text,就是文本值
1.5、appendChild 添加节点元素,一层层自己控制
1.6、Transformer 把document转成String
1.7、FileOutputStream 打开,写入String.getBytes(),关闭流

/**写入XML数据*/
    private void WriteXmlToSdcardByDom(){
        List<DeviceInfo> deviceInfoList = new ArrayList<>();
        DeviceInfo deviceInfo = new DeviceInfo("仪器123",1,188,"YYY","检测兽药残留");
        DeviceInfo deviceInfo3 = new DeviceInfo("仪器456",2,199,"XXX","检测农药残留及多参数");
        deviceInfoList.add(deviceInfo);
        deviceInfoList.add(deviceInfo3);

        try {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder documentBuilder = null;
            documentBuilder = documentBuilderFactory.newDocumentBuilder();
            Document document = documentBuilder.newDocument();
            document.setXmlStandalone(true);
            document.setXmlVersion("1.0");

            //根节点
            Element root = document.createElement("xml_data");
            //user节点
            Element userE = document.createElement("user");
            userE.setAttribute("name","wujn");
            root.appendChild(userE);
            //deviceinfos节点
            Element devsE = document.createElement("deviceinfos");
            for(int i=0;i<deviceInfoList.size();i++){
                //单个deviceinfo节点
                Element devE = document.createElement("deviceinfo");
                devE.setAttribute("id",String.valueOf(deviceInfoList.get(i).getId()));

                Element nameE = document.createElement("name");
                nameE.setTextContent(deviceInfoList.get(i).getName());
                devE.appendChild(nameE);

                Element priceE = document.createElement("price");
                priceE.setTextContent(String.valueOf(deviceInfoList.get(i).getPrice()));
                devE.appendChild(priceE);

                Element companyE = document.createElement("company");
                companyE.setTextContent(deviceInfoList.get(i).getCompany());
                devE.appendChild(companyE);

                Element usageE = document.createElement("usage");
                usageE.setTextContent(deviceInfoList.get(i).getUsage());
                devE.appendChild(usageE);

                //添加deviceinfo节点
                devsE.appendChild(devE);
            }
            root.appendChild(devsE);
            document.appendChild(root);


            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();

            //转成string
            transformer.setOutputProperty("encoding","utf-8");
            StringWriter stringWriter = new StringWriter();
            transformer.transform(new DOMSource(document),new StreamResult(stringWriter));
            LogUtil.i("xml stream = "+stringWriter.toString());

            //xml文件的序列号器  帮助生成一个xml文件
            FileOutputStream fos = new FileOutputStream(new File(xmlPath));
            fos.write(stringWriter.toString().getBytes());
            //写入流关闭
            fos.flush();
            fos.close();

            ToastUtil.showShort(instance,"xml数据已导出");

        } catch (IllegalArgumentException e) {
            e.printStackTrace();
            ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());
        } catch (IllegalStateException e) {
            e.printStackTrace();
            ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());
        } catch (IOException e) {
            e.printStackTrace();
            ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());
        }catch (ParserConfigurationException e) {
            e.printStackTrace();
            ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());
        }catch (TransformerConfigurationException e) {
            e.printStackTrace();
            ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());
        }catch (TransformerException e) {
            e.printStackTrace();
            ToastUtil.showShort(instance,"xml数据导出异常:"+e.getMessage());
        }

    }

四、读取

1、XmlPullParser - Pull形式,一行行解析的,减少内存消耗

1、xml解析器设置解读编码和FileInputStream
2、getEventType 获得tag标签类型,按照不同类型进行解析
XmlResourceParser.END_DOCUMENT
XmlResourceParser.START_TAG
XmlResourceParser.TEXT - 标签内文本content-text
XmlResourceParser.END_TAG
3、next() 下一行,还有nextTag,nextText等
5、数据整合
6、关闭FileInputStream流

注意://如果xml节点确定是文本,需要检查XmlResourceParser.TEXT,防止getText() 返回 null。
/**
     * XmlPullParser - 读取XML数据
     * 逻辑上有可能有不严谨的地方
     * */
    private void ReadXmlFromSdcardByPull(){
        File xmlFile = new File(xmlPath);
        if(xmlFile.exists()){

            try {
                StringBuilder sb = new StringBuilder();
                sb.append(" -- XmlPullParser --\n");
                List<DeviceInfo> deviceInfoList = new ArrayList<>();
                DeviceInfo deviceInfo = null;
                boolean convertDeviceInfo = false;

                //文件写入流
                FileInputStream fis = new FileInputStream(xmlFile);
                //xml解析
                XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
                factory.setNamespaceAware(true);
                XmlPullParser xrp = factory.newPullParser();
                //设置input encode
                xrp.setInput(fis, "UTF-8");


                while (xrp.getEventType() != XmlResourceParser.END_DOCUMENT) {
                    if (xrp.getEventType() == XmlResourceParser.START_TAG) {
                        String tagName = xrp.getName();

                        if (tagName.equals("user")) {
                            String name = xrp.getAttributeValue(null, "name");
                            sb.append("user.name="+name+"\n");
                        }

                        else if(tagName.equals("deviceinfos")){
                            //nothing to do
                        }

                        else if(tagName.equals("deviceinfo")){
                            deviceInfo = new DeviceInfo();
                            int id = Integer.parseInt(xrp.getAttributeValue(null, "id"));
                            deviceInfo.setId(id);
                            LogUtil.d("id="+id);
                            convertDeviceInfo = true;
                        }

                        //解析 DeviceInfo
                        //<StartTag>text<EndTag> 是三个元素
                        if(convertDeviceInfo){
                            if(tagName.equals("name")) {
                                xrp.next();
                                //必须检查如果当前 xml 节点是文本,以便 getText() 不会返回 null。
                                if (xrp.getEventType() == XmlResourceParser.TEXT){
                                    String name = xrp.getText();
                                    deviceInfo.setName(name);
                                    LogUtil.d("name="+name);
                                }
                                xrp.next();

                            }

                            else if(tagName.equals("price")){
                                xrp.next();
                                if (xrp.getEventType() == XmlResourceParser.TEXT){
                                    int price = Integer.parseInt(xrp.getText());
                                    deviceInfo.setPrice(price);
                                    LogUtil.d("price="+price);
                                }
                                xrp.next();
                            }

                            else if(tagName.equals("company")){
                                xrp.next();
                                if (xrp.getEventType() == XmlResourceParser.TEXT){
                                    String company = xrp.getText();
                                    deviceInfo.setCompany(company);
                                    LogUtil.d("company="+company);
                                }
                                xrp.next();
                            }

                            else if(tagName.equals("usage")){
                                xrp.next();
                                if (xrp.getEventType() == XmlResourceParser.TEXT){
                                    String usage = xrp.getText();
                                    deviceInfo.setUsage(usage);
                                    LogUtil.d("usage="+usage);
                                }
                                xrp.next();
                            }
                        }

                    }

                    else if(xrp.getEventType() == XmlResourceParser.END_TAG){
                        String tagName = xrp.getName();
                        if(tagName.equals("deviceinfo")){
                            deviceInfoList.add(deviceInfo);
                            deviceInfo = null;
                            convertDeviceInfo = false;
                        }
                    }
                    //xrp.nextTag();
                    //xrp.nextText();
                    xrp.next();
                }

                //关闭流
                fis.close();
                fis=null;

                for (int i=0;i<deviceInfoList.size();i++){
                    sb.append(deviceInfoList.get(i).toString()+"\n");
                }

                tv_result.setText(sb.toString());

            } catch (IllegalArgumentException e) {
                e.printStackTrace();
                ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());
            } catch (IllegalStateException e) {
                e.printStackTrace();
                ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());
            } catch (IOException e) {
                e.printStackTrace();
                ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());
            } catch (XmlPullParserException e) {
                e.printStackTrace();
                ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());
            }

        }else{
            ToastUtil.showShort(instance,"xml文件不存在");
        }

    }

2、SAXParser - SAX形式

1、sax解析器设置FileInputStream 和解析助手handler
2、解析助手TestXmlHandler extends DefaultHandler
startDocument 开始文档
endDocument 结束文档
startElement 元素开始 :localName=tag标签名,attribute元素.getValue()获取元素值
endElement 元素结束
characters 元素内content-text
3、FileInputStream 刘关闭

注意:org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 76: junk after document element 这个异常是要么解析器解析写错了,要么就是xml文档不规范,比如顶层元素有多个,规定标准是只有一个顶层元素,在这里是xml_data
/**
     * SAXParser - 读取XML数据
     * 逻辑上有可能有不严谨的地方
     *
     * org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 76: junk after document element
     * 顶层元素不止一个的异常
     * */
    private void ReadXmlFromSdcardBySAX(){
        File xmlFile = new File(xmlPath);
        if(xmlFile.exists()){
            try {
                final StringBuilder sb = new StringBuilder();
                sb.append(" -- SAXParser --\n");

                //文件写入流
                FileInputStream fis = new FileInputStream(xmlFile);

                SAXParserFactory spf = SAXParserFactory.newInstance();
                SAXParser saxParser = spf.newSAXParser();//创建解析器
                //设置解析器的相关特性,http://xnl.org/sax/features/namespaces = true;
                //表示开启命名空间特性
                //saxParser.setProperty("http://xnl.org/sax/features/namespaces", true);
                TestXmlHandler handler = new TestXmlHandler() {
                    @Override
                    void onStart() {
                        LogUtil.i("SAXParser onStart >>> ");
                    }

                    @Override
                    void onEnd(String username, List<DeviceInfo> deviceInfoList) {
                        LogUtil.i("SAXParser onEnd >>> ");

                        sb.append("user.name="+username+"\n");
                        for (int i=0;i<deviceInfoList.size();i++){
                            sb.append(deviceInfoList.get(i).toString()+"\n");
                        }

                        tv_result.setText(sb.toString());
                    }
                };
                saxParser.parse(fis, handler);

//                InputSource inputSource = new InputSource();
//                inputSource.setEncoding("utf-8");
//                inputSource.setCharacterStream(new StringReader(xmlPath));
//                saxParser.parse(new InputSource(new FileReader(new File(xmlPath))), handler);

                //关闭流
                fis.close();
                fis=null;

            }catch (IOException e){
                e.printStackTrace();
                ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());
            }catch (SAXException e){
                e.printStackTrace();
                ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());
            }catch (ParserConfigurationException e){
                e.printStackTrace();
                ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());
            }

        }else{
            ToastUtil.showShort(instance,"xml文件不存在");
        }

    }


    /**
     * TestXmlHandler - SAX的解析器
     * 靠preTag也可以达到convertDeviceInfo类似的效果
     * */
    abstract class TestXmlHandler extends DefaultHandler{
        private String username = "";
        private List<DeviceInfo> deviceInfoList = new ArrayList<>();
        private DeviceInfo deviceInfo = null;
        private boolean convertDeviceInfo = true;

        private String preTag;//之前tag

        @Override
        public void startDocument() throws SAXException {
            onStart();
        }
        @Override
        public void endDocument() throws SAXException {
            onEnd(username, deviceInfoList);
        }
        abstract void onStart();
        abstract void onEnd(String username,List<DeviceInfo> deviceInfoList);

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            LogUtil.d("startElement: uri="+uri+", localName="+localName+", qName="+qName);
            preTag = localName;

            if("user".equals(localName)){
                username = attributes.getValue("name");
            }

            else if("deviceinfos".equals(localName)){
                //will be more deviceinfo
            }

            else if("deviceinfo".equals(localName)){
                deviceInfo = new DeviceInfo();
                int id = Integer.parseInt(attributes.getValue("id"));
                deviceInfo.setId(id);
                convertDeviceInfo = true;
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            LogUtil.d("endElement: uri="+uri+", localName="+localName+", qName="+qName);
            preTag = null;

            if("deviceinfo".equals(localName)){
                deviceInfoList.add(deviceInfo);
                deviceInfo = null;
                convertDeviceInfo = false;
            }
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            String data = new String(ch,start,length);
            LogUtil.d("characters: preTag="+preTag+", data="+data);

            if(convertDeviceInfo){
                if(preTag.equals("name")) {
                    deviceInfo.setName(data);
                    LogUtil.d("name="+data);
                }

                else if(preTag.equals("price")){
                    int price = Integer.parseInt(data);
                    deviceInfo.setPrice(price);
                    LogUtil.d("price="+price);
                }

                else if(preTag.equals("company")){
                    deviceInfo.setCompany(data);
                    LogUtil.d("company="+data);
                }

                else if(preTag.equals("usage")){
                    deviceInfo.setUsage(data);
                    LogUtil.d("usage="+data);
                }
            }
        }


    }

3、Document - dom形式:此方式需要读取整个流数据,占用内存较大,一般针对小型xml数据可以用此方法,有点在于简单易懂

1、document加载输入流
2、getElementsByTagName 获得该tag名下的所有节点
3、每个node(Element)都有获取属性,属性name和值.getAttributes().getNamedItem("name").getNodeValue()
4、每个node(Element)的文本值 content-text : getTextContent();
5、关闭输入流

/**
     * Document - 读取XML数据
     * 直观明了,但是要预加载所有数据,对xml比较大占内存比较多
     * */
    private void ReadXmlFromSdcardByDom(){
        File xmlFile = new File(xmlPath);
        if(xmlFile.exists()){
            try {
                StringBuilder sb = new StringBuilder();
                sb.append(" -- Document --\n");

                DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder documentBuilder = null;
                documentBuilder = documentBuilderFactory.newDocumentBuilder();

                //加载输入流到document中
                //InputStream inputStream = getAssets().open("person.xml");
                FileInputStream fis = new FileInputStream(xmlFile);
                Document document = documentBuilder.parse(fis);

                NodeList userNodes = document.getElementsByTagName("user");
                for(int i=0;i<userNodes.getLength();i++){
                    sb.append("user.name="+userNodes.item(i).getAttributes().getNamedItem("name").getNodeValue()+"\n");
                }

                List<DeviceInfo> deviceInfoList = new ArrayList<>();
                DeviceInfo deviceInfo = null;
                NodeList deviceNodes = document.getElementsByTagName("deviceinfo");
                //设备节点
                for(int i=0;i<deviceNodes.getLength();i++){
                    deviceInfo = new DeviceInfo();
                    Node deviceNode = deviceNodes.item(i);
                    int id = Integer.parseInt(deviceNode.getAttributes().getNamedItem("id").getNodeValue());
                    LogUtil.d("id="+id);
                    deviceInfo.setId(id);

                    NodeList eachDeviceNodes = deviceNode.getChildNodes();
                    LogUtil.d("eachDeviceNodes.length="+eachDeviceNodes.getLength());
                    //设备下值节点
                    for(int j=0;j<eachDeviceNodes.getLength();j++){
                        String tagName = eachDeviceNodes.item(j).getNodeName();//nodename not localname
                        LogUtil.d("tagName=" + tagName);
                        String data = eachDeviceNodes.item(j).getTextContent();

                        if (tagName.equals("name")) {
                            deviceInfo.setName(data);
                            LogUtil.d("name=" + data);
                        } else if (tagName.equals("price")) {
                            int price = Integer.parseInt(data);
                            deviceInfo.setPrice(price);
                            LogUtil.d("price=" + price);
                        } else if (tagName.equals("company")) {
                            deviceInfo.setCompany(data);
                            LogUtil.d("company=" + data);
                        } else if (tagName.equals("usage")) {
                            deviceInfo.setUsage(data);
                            LogUtil.d("usage=" + data);
                        }

                    }
                    //添加设备到列表
                    deviceInfoList.add(deviceInfo);
                }

                //关闭流
                fis.close();
                fis=null;

                for (int i=0;i<deviceInfoList.size();i++){
                    sb.append(deviceInfoList.get(i).toString()+"\n");
                }

                tv_result.setText(sb.toString());

            }catch (IOException e){
                e.printStackTrace();
                ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());
            }catch (ParserConfigurationException e){
                e.printStackTrace();
                ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());
            }catch (SAXException e){
                e.printStackTrace();
                ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());
            }
        }else{
            ToastUtil.showShort(instance,"xml文件不存在");
        }
    }

4、Jsoup- 和上面dom类似

1、Jsoup.parse 、Jsoup.connect 加载url或者htmlstring或者文件
2、getElementsByTag 获得该tag名下的所有节点,
3、children() 获得某节点元素下的所有元素
4、每个Element都有获取属性,attr(key)
5、每个Element的文本值 content-text : text();

compile 'org.jsoup:jsoup:1.9.2'
/**
     * Jsoup - 读取XML数据(本质是document)
     * 直观明了,但是要预加载所有数据,对xml比较大占内存比较多
     * */
    private void ReadXmlFromSdcardByJsoup(){
        File xmlFile = new File(xmlPath);
        if(xmlFile.exists()){
            try {
                StringBuilder sb = new StringBuilder();
                sb.append(" -- Jsoup --\n");

                //url网址作为输入源
                //Document doc = Jsoup.connect("http://www.example.com").timeout(60000).get();

                //File文件作为输入源
                //File input = new File("/tmp/input.html");
                //Document doc = Jsoup.parse(input, "UTF-8", "http://www.example.com/");

                org.jsoup.nodes.Document document = Jsoup.parse(xmlFile, "UTF-8");
                org.jsoup.select.Elements userE = document.getElementsByTag("user");
                for(int i=0;i<userE.size();i++){
                    sb.append("user.name="+userE.get(i).attr("name")+"\n");
                }


                List<DeviceInfo> deviceInfoList = new ArrayList<>();
                DeviceInfo deviceInfo = null;
                org.jsoup.select.Elements deviceE = document.getElementsByTag("deviceinfo");
                //设备节点
                for(int i=0;i<deviceE.size();i++){
                    deviceInfo = new DeviceInfo();
                    org.jsoup.nodes.Element devE = deviceE.get(i);
                    int id = Integer.parseInt(devE.attr("id"));
                    LogUtil.d("id="+id);
                    deviceInfo.setId(id);

                    org.jsoup.select.Elements eachDeviceElements = devE.children();
                    LogUtil.d("eachDeviceElements.length="+eachDeviceElements.size());
                    //设备下值节点
                    for(int j=0;j<eachDeviceElements.size();j++){
                        String tagName = eachDeviceElements.get(j).tagName();
                        String data = eachDeviceElements.get(j).text();
                        LogUtil.d("tagName=" + tagName + ", text="+data);

                        if (tagName.equals("name")) {
                            deviceInfo.setName(data);
                        } else if (tagName.equals("price")) {
                            int price = Integer.parseInt(data);
                            deviceInfo.setPrice(price);
                        } else if (tagName.equals("company")) {
                            deviceInfo.setCompany(data);
                        } else if (tagName.equals("usage")) {
                            deviceInfo.setUsage(data);
                        }

                    }

                    //添加设备到列表
                    deviceInfoList.add(deviceInfo);
                }

                //关闭流
                //fis.close();
                //fis=null;

                for (int i=0;i<deviceInfoList.size();i++){
                    sb.append(deviceInfoList.get(i).toString()+"\n");
                }

                tv_result.setText(sb.toString());



            }catch (IOException e){
                e.printStackTrace();
                ToastUtil.showShort(instance,"xml数据导入异常:"+e.getMessage());
            }
        }else{
            ToastUtil.showShort(instance,"xml文件不存在");
        }
    }

五、读取和写入文本

/**
     * 从file文件中读取string来
     * */
    public static String readFromFile(String fPath) throws IOException{
        BufferedReader bf = new BufferedReader(new FileReader(fPath));

        String content = "";
        StringBuilder sb = new StringBuilder();

        while (content != null) {
            content = bf.readLine();
            if (content == null) {
                break;
            }
            sb.append(content.trim());
        }
        bf.close();

        return sb.toString();
    }

    /**
     * 写string到file文件中
     * */
    public static void writeToFile(String content,String fPath)throws IOException{
        File txt = new File(fPath);
        if (!txt.exists()) {
            txt.createNewFile();
        }

        FileOutputStream fos = new FileOutputStream(txt);
        fos.write(content.getBytes());
        fos.flush();
        fos.close();
    }
目录
相关文章
|
27天前
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
106 4
|
1月前
|
JavaScript 前端开发 开发者
判断哪些数据的变化需要触发虚拟 DOM 的更新
判断哪些数据的变化需要触发虚拟 DOM 的更新,需要依据框架的响应式原理、组件的状态管理以及各种用户交互和异步操作等多方面因素。开发者需要深入理解所使用框架的工作机制,合理地组织和管理数据,以确保虚拟 DOM 的更新是高效且必要的。
25 2
|
4月前
|
开发工具 Android开发 开发者
Android平台如何不推RTMP|不发布RTSP流|不实时录像|不回传GB28181数据时实时快照?
本文介绍了一种在Android平台上实现实时截图快照的方法,尤其适用于无需依赖系统接口的情况,如在RTMP推送、RTSP服务或GB28181设备接入等场景下进行截图。通过底层模块(libSmartPublisher.so)实现了截图功能,封装了`SnapShotImpl.java`类来管理截图流程。此外,提供了关键代码片段展示初始化SDK实例、执行截图、以及在Activity销毁时释放资源的过程。此方案还考虑到了快照数据的灵活处理需求,符合GB/T28181-2022的技术规范。对于寻求更灵活快照机制的开发者来说,这是一个值得参考的设计思路。
|
2月前
|
存储 大数据 数据库
Android经典面试题之Intent传递数据大小为什么限制是1M?
在 Android 中,使用 Intent 传递数据时存在约 1MB 的大小限制,这是由于 Binder 机制的事务缓冲区限制、Intent 的设计初衷以及内存消耗和性能问题所致。推荐使用文件存储、SharedPreferences、数据库存储或 ContentProvider 等方式传递大数据。
88 0
|
4月前
|
存储 Java 数据库
基于全志H713 Android 11:给TvSettings添加default.xml默认值
本文介绍了在全志H713 Android 11平台上为TvSettings应用添加HDMI CEC功能的默认设置值的方法,通过修改SettingsProvider的源码和配置文件来实现默认值的设置,并提供了详细的步骤和测试结果。
103 0
基于全志H713 Android 11:给TvSettings添加default.xml默认值
|
4月前
|
JSON Java Android开发
Android 开发者必备秘籍:轻松攻克 JSON 格式数据解析难题,让你的应用更出色!
【8月更文挑战第18天】在Android开发中,解析JSON数据至关重要。JSON以其简洁和易读成为首选的数据交换格式。开发者可通过多种途径解析JSON,如使用内置的`JSONObject`和`JSONArray`类直接操作数据,或借助Google提供的Gson库将JSON自动映射为Java对象。无论哪种方法,正确解析JSON都是实现高效应用的关键,能帮助开发者处理网络请求返回的数据,并将其展示给用户,从而提升应用的功能性和用户体验。
110 1
|
4月前
|
缓存 API Android开发
Android经典实战之Kotlin Flow中的3个数据相关的操作符:debounce、buffer和conflate
本文介绍了Kotlin中`Flow`的`debounce`、`buffer`及`conflate`三个操作符。`debounce`过滤快速连续数据,仅保留指定时间内的最后一个;`buffer`引入缓存减轻背压;`conflate`仅保留最新数据。通过示例展示了如何在搜索输入和数据流处理中应用这些操作符以提高程序效率和用户体验。
57 6
|
4月前
|
编解码 网络协议 前端开发
如何实现Android平台GB28181设备接入模块按需打开摄像头并回传数据
后台采集摄像头,如果想再进一步扩展,可以把android平台gb28181的camera2 demo,都移植过来,实现功能更强大的国标设备侧,这里主要是展示,收到国标平台侧的回传请求后,才打开摄像头,才开始编码打包,最大限度的减少资源的占用
|
4月前
|
编解码 网络协议 Android开发
Android平台GB28181设备接入模块实现后台service按需回传摄像头数据到国标平台侧
我们在做Android平台GB28181设备对接模块的时候,遇到这样的技术需求,开发者希望能以后台服务的形式运行程序,国标平台侧没有视频回传请求的时候,仅保持信令链接,有发起视频回传请求或语音广播时,打开摄像头,并实时回传音视频数据或接收处理国标平台侧发过来的语音广播数据。
|
4月前
|
算法 数据处理 开发工具
Android平台RTSP|RTMP播放器如何回调YUV或RGB数据
在开发Android平台上的RTSP或RTMP播放器时,开发者不仅追求低延迟播放,还希望获取解码后的视频数据(如YUV或RGB格式),以便进行视觉算法分析。使用大牛直播SDK中的SmartPlayer,可在确保播放流畅的同时,通过设置外部渲染器(`SmartPlayerSetExternalRender`)来高效地回调原始视频数据。例如,对于RGBA数据,需实现`NTExternalRender`接口,并重写相关方法以处理数据和尺寸变化。同样地,对于I420(YUV)数据,也需要相应地实现接口以满足需求。这种方式使得开发者能在不影响常规播放功能的情况下,进行定制化的视频处理任务。