如何从Android的Kotlin中的URL链接解析XML

时间:2019-02-17 09:14:36

标签: android xml parsing url kotlin

我试图从URL链接解析xml,例如:http://a.cdn.searchspring.net/help/feeds/sample.xml,我可以从文件而不是URL链接解析它。这是我的代码:

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.SimpleAdapter
import android.widget.ListView
import org.w3c.dom.Element
import org.w3c.dom.Node
import org.xml.sax.InputSource
import org.xml.sax.SAXException
import java.io.IOException
import java.net.URL
import javax.xml.parsers.DocumentBuilderFactory
import javax.xml.parsers.ParserConfigurationException

class MainActivity : AppCompatActivity() {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var empDataHashMap = HashMap<String, String>()
        var empList: ArrayList<HashMap<String, String>> = ArrayList()
        var url = URL("http://a.cdn.searchspring.net/help/feeds/sample.xml")

            val lv = findViewById<ListView>(R.id.listView)

            // Using a background thread to do network code
            val thread = object : Thread() {
                override fun run() {
                    try {
                        // Comment-out this line of code
                        // val istream = assets.open("empdetail.xml")
                        val builderFactory = DocumentBuilderFactory.newInstance()
                        val docBuilder = builderFactory.newDocumentBuilder()
                        val doc = docBuilder.parse(InputSource(url.openStream()))
                        // reading player tags
                        val nList = doc.getElementsByTagName("Product")
                        for (i in 0 until nList.length) {
                            if (nList.item(0).nodeType.equals(Node.ELEMENT_NODE)) {
                                empDataHashMap = HashMap()
                                val element = nList.item(i) as Element
                                empDataHashMap.put("name", getNodeValue("name", element))
                                empDataHashMap.put("id", getNodeValue("id", element))
                                empDataHashMap.put("brand", getNodeValue("brand", element))

                                empList.add(empDataHashMap)
                            }
                        }

                        val adapter = SimpleAdapter(
                                this@MainActivity,
                                empList,
                                R.layout.custom_list,
                                arrayOf("name", "id", "brand"),
                                intArrayOf(R.id.name, R.id.ratings, R.id.role)
                        )

                        runOnUiThread {
                            lv.setAdapter(adapter)
                        }
                    } catch (e: IOException) {
                        e.printStackTrace()
                    } catch (e: ParserConfigurationException) {
                        e.printStackTrace()
                    } catch (e: SAXException) {
                        e.printStackTrace()
                    }
                }
            }

            thread.start()
        }


    //return node value
    public fun getNodeValue(tag: String, element: Element): String{
        val nodeList = element.getElementsByTagName(tag)
        val node = nodeList.item(0)
        if(node != null){
            if(node.hasChildNodes()){
                val child = node.firstChild
                while(child!=null){
                    if(child.nodeType === org.w3c.dom.Node.TEXT_NODE)
                    {
                        return child.nodeValue
                    }
                }
            }
        }
        return ""
    }
}

我还在清单文件中添加了Internet许可。在运行代码时,此代码在运行时没有任何警告。但是只有空的活动来了。那里没有数据显示。

2 个答案:

答案 0 :(得分:0)

有3个问题可能会使您的应用无法正常工作。

  • 您的设备未连接到Internet,因此请确保Internet连接可用。
  • 由于某些原因,empdetail.xml文件夹中不存在assetsassets文件夹放置在错误的位置,则应用程序将抛出FileNotFoundExceptionIOException),因为您抓住了IOException,因此您的应用可以正常运行,但什么也不显示,因此请尝试注释掉代码行val istream = assets.open("empdetail.xml")
  • 您要从网络获取数据(xml文件),必须将网络代码放在后台线程而不是UI线程中。几乎所有的设备都会抛出NetworkOnMainThreadException,但是有些设备会将其静音。

全部放在一起。

var empDataHashMap = HashMap<String, String>()
var empList: ArrayList<HashMap<String, String>> = ArrayList()
var url = URL("http://a.cdn.searchspring.net/help/feeds/sample.xml")

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val lv = findViewById<ListView>(R.id.listView)

    // Using a background thread to do network code
    val thread = object : Thread() {
        override fun run() {
            try {
                // Comment-out this line of code
                // val istream = assets.open("empdetail.xml")
                val builderFactory = DocumentBuilderFactory.newInstance()
                val docBuilder = builderFactory.newDocumentBuilder()
                val doc = docBuilder.parse(InputSource(url.openStream()))
                // reading player tags
                val nList = doc.getElementsByTagName("Product")
                for (i in 0 until nList.length) {
                    if (nList.item(0).nodeType.equals(Node.ELEMENT_NODE)) {
                        empDataHashMap = HashMap()
                        val element = nList.item(i) as Element
                        empDataHashMap.put("name", getNodeValue("name", element))
                        empDataHashMap.put("id", getNodeValue("id", element))
                        empDataHashMap.put("brand", getNodeValue("brand", element))

                        empList.add(empDataHashMap)
                    }
                }

                val adapter = SimpleAdapter(
                    this@MainActivity,
                    empList,
                    R.layout.custom_list,
                    arrayOf("name", "id", "brand"),
                    intArrayOf(R.id.name, R.id.ratings, R.id.role)
                )

                runOnUiThread {
                    lv.setAdapter(adapter)
                }
            } catch (e: IOException) {
                e.printStackTrace()
            } catch (e: ParserConfigurationException) {
                e.printStackTrace()
            } catch (e: SAXException) {
                e.printStackTrace()
            }
        }
    }

    thread.start()
}

答案 1 :(得分:0)

我认为您使用了错误的方法从 url 获取 xml。 您应该从 url 请求数据。

在java中是这样的:

HttpURLConnection connection = null;
    try {
        URL url = new URL(target);
        connection = (HttpURLConnection) url.openConnection();
        connection.setRequestMethod("GET");
        connection.setUseCaches(false);
        connection.connect();
    }

并使用它来获取字符串中的数据:

BufferedReader br = new BufferedReader(new InputStreamReader(connection.getInputStream(), StandardCharsets.UTF_8));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) {
    sb.append(line).append("\n");
}
br.close();
return sb.toString();

希望这会有所帮助。