2

又是一个问题。这次我正在解析从服务器接收到的 XML 消息。有人认为自己很聪明,决定将 HTML 页面放在 XML 消息中。现在我有点面临问题,因为我想从这个 XML 消息中提取那个 HTML 页面作为字符串。

好的,这是我正在解析的 XML 消息:

<AmigoRequest> <From></From> <To></To> <MessageType>showMessage</MessageType> <Param0>general message</Param0> <Param1><html><head>test</head><body>Testhtml</body></html></Param1> </AmigoRequest>

您会看到在 Param1 中指定了一个 HTML 页面。我尝试通过以下方式提取消息:

公共字符串 getParam1(文档 d){
        if (d.getDocumentElement().getTagName().equals("AmigoRequest")) {
            NodeList 结果 = d.getElementsByTagName("Param1");
            // 消息类型取决于我们正在阅读的消息。           
            if (results.getLength() > 0 && results != null) {                
                返回结果.item(0).getFirstChild().getNodeValue();
            }
        }
        返回 ””;
    }

其中 d 是文档形式的 XML 消息。它总是返回一个空值,因为 getNodeValue() 返回空值。当我尝试 results.item(0).getFirstChild().hasChildNodes() 时,它会返回 true,因为他看到消息中有一个标签。

如何<html><head>test</head><body>Testhtml</body></html>从字符串中的 Param0 中提取 html 消息?

我正在使用 Android sdk 1.5(几乎是 java)和 DOM Parser。

感谢您的时间和回复。

安泰克

4

5 回答 5

1

经过大量检查并挠头数千次后,我想出了一个简单的更改,即需要将您的 API 级别更改为 8

于 2011-01-31T11:18:30.210 回答
1

您可以获取 param1 的内容,如下所示:

public String getParam1(Document d) {
        if (d.getDocumentElement().getTagName().equals("AmigoRequest")) {
            NodeList results = d.getElementsByTagName("Param1");
            // Messagetype depends on what message we are reading.           
            if (results.getLength() > 0 && results != null) {                

                // String extractHTMLTags(String s) is a function that you have 
                // to implement in a way that will extract all the HTML tags inside a string.
                return extractHTMLTags(results.item(0).getTextContent());
            }
        }
        return "";
    }

您所要做的就是实现一个功能:

String extractHTMLTags(String s)

这将从字符串中删除所有出现的 HTML 标记。为此,您可以查看这篇文章:Remove HTML tags from a String

于 2010-01-12T17:19:40.447 回答
0

好吧,我几乎与代码在那里......

public String getParam1(Document d) {
    if (d.getDocumentElement().getTagName().equals("AmigoRequest")) {
        NodeList results = d.getElementsByTagName("Param1");
        // Messagetype depends on what message we are reading.           
        if (results.getLength() > 0 && results != null) {                
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db;
            Element node = (Element) results.item(0); // get the value of Param1
            Document doc2 = null;
            try {

                db = dbf.newDocumentBuilder();
                doc2 = db.newDocument(); //create new document
                doc2.appendChild(doc2.importNode(node, true)); //import the <html>...</html> result in doc2

            } catch (ParserConfigurationException e) {
                // TODO Auto-generated catch block
                Log.d(TAG, " Exception ", e);
            } catch (DOMException e) {
                // TODO: handle exception
                Log.d(TAG, " Exception ", e);
            } catch (Exception e) {
                // TODO: handle exception
                e.printStackTrace();               }              


            return doc2. .....// All I'm missing is something to convert a Document to a string.
        }
    }
    return "";

}

就像我的代码评论中解释的那样。我所缺少的就是从文档中创建一个字符串。您不能在 Android 中使用 Transform 类... doc2.toString() 将为您提供对象的序列化..

但是如果这不起作用,我的下一步是编写我自己的解析器;)

不是最好的代码,而是临时的解决方案。

public String getParam1(String b) {
        return b
                .substring(b.indexOf("<Param1>") + "<Param1>".length(), b.indexOf("</Param1>"));
    }

其中 String b 是 XML 文档字符串。

于 2010-01-13T13:29:07.443 回答
0

编辑:我刚刚看到您在上面关于getTextContent()不受 Android 支持的评论。我将保留这个答案,以防它对不同平台上的人有用。

如果你的 DOM API 支持,你可以调用getTextContent(),如下:

public String getParam1(Document d) {
        if (d.getDocumentElement().getTagName().equals("AmigoRequest")) {
            NodeList results = d.getElementsByTagName("Param1");
            // Messagetype depends on what message we are reading.           
            if (results != null) {                
                return results.getTextContent();
            }
        }
        return "";
    }

但是,getTextContent()是 DOM Level 3 API 调用;并非所有解析器都保证支持它。Xerces-J 确实如此

顺便说一句,在你原来的例子中,你的检查null是在错误的地方;它应该是:

        if (results != null && results.getLength() > 0) {                

否则,如果results真的以null.

于 2010-01-12T17:38:42.857 回答
0

由于getTextContent()您无法使用,因此另一种选择是编写它——这并不难。事实上,如果你只是为了自己的使用而写这篇文章——或者你的雇主对开源没有过于严格的规定——你可以将Apache 的实现作为一个起点;第 610-646 行似乎包含了您需要的大部分内容。(请尊重 Apache 的版权和许可。)

否则,该方法的一些粗略伪代码将是:

String getTextContent(Node node) {
    if (node has no children) 
        return "";

    if (node has 1 child)
        return getTextContent(node.getFirstChild());

    return getTextContent(new StringBuffer()).toString();
}

StringBuffer getTextContent(Node node, StringBuffer sb) {
    for each child of node {
        if (child is a text node) sb.append(child's text)
        else getTextContent(child, sb);
    }
    return sb;
}
于 2010-01-12T18:24:46.820 回答