Java 仅从XML元素中的实体编码HTML提取文本

Java 仅从XML元素中的实体编码HTML提取文本,java,android,xml,xml-parsing,Java,Android,Xml,Xml Parsing,我正在开发一个XML解析Android应用程序,但我有一个问题。我要分析的页面有一个元素,其中有时会出现不需要的实体编码的HTML。结构如下: <description>&lt;img src="http://images.website.it/thumbs/images/2014/12/16/asd_crop_upscale_q85.jpg" alt="Post img " style="float:left;margin-right:10px"/&gt; Lore

我正在开发一个XML解析Android应用程序,但我有一个问题。我要分析的页面有一个元素
,其中有时会出现不需要的实体编码的HTML。结构如下:

<description>&lt;img src="http://images.website.it/thumbs/images/2014/12/16/asd_crop_upscale_q85.jpg" alt="Post img " style="float:left;margin-right:10px"/&gt; Lorem ipsum...</description>
这是我第一次解析XML,所以我不知道如何才能做到这一点

顺便说一下,这是我的
XMLParser
类:

public class XMLParser {

    // constructor
    public XMLParser() {

    }

    /**
     * Getting XML from URL making HTTP request
     *
     * @param url string
     */
    public String getXmlFromUrl(String url) {
        String xml = null;

        try {
            // defaultHttpClient
            DefaultHttpClient httpClient = new DefaultHttpClient();
            HttpPost httpPost = new HttpPost(url);

            HttpResponse httpResponse = httpClient.execute(httpPost);
            HttpEntity httpEntity = httpResponse.getEntity();
            xml = EntityUtils.toString(httpEntity);

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // return XML
        return xml;
    }

    /**
     * Getting XML DOM element
     *
     * @param XML string
     */
    public Document getDomElement(String xml) {
        Document doc = null;
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        try {

            DocumentBuilder db = dbf.newDocumentBuilder();

            InputSource is = new InputSource();
            is.setCharacterStream(new StringReader(xml));
            doc = db.parse(is);

        } catch (ParserConfigurationException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        } catch (SAXException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        } catch (IOException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        }

        return doc;
    }

    /**
     * Getting node value
     *
     * @param elem element
     */
    public final String getElementValue(Node elem) {
        Node child;
        if (elem != null) {
            if (elem.hasChildNodes()) {
                for (child = elem.getFirstChild(); child != null;
                        child = child.getNextSibling()) {
                    if (child.getNodeType() == Node.TEXT_NODE) {
                        return child.getNodeValue();
                    }
                }
            }
        }
        return "";
    }

    /**
     * Getting node value
     *
     * @param Element node
     * @param key string
     */
    public String getValue(Element item, String str) {
        NodeList n = item.getElementsByTagName(str);
        return this.getElementValue(n.item(0));
    }
}

我用新的
doInBackground
方法编辑我的任务。没有任何更改

如果要放弃在
description
元素中找到的所有实体编码的HTML,则可以使用正则表达式查找所有编码的HTML标记并将其替换为空字符串,然后修剪生成的字符串以去掉不需要的前导和尾随空格

您可以只使用一次,但是如果您要多次使用,那么创建一个
模式
对象一次,然后每次都使用它是值得的。这避免了Java运行时必须多次编译相同的正则表达式

我已经测试了这段代码,它针对您问题中的示例XML工作:

private static final Pattern ENTITY_ENCODED_HTML_TAG =
        Pattern.compile("&lt;.*?&gt;");

public static void main(String[] args) {
    String descriptionElementContent =
            "&lt;img src=\"http://images.website.it/thumbs/images/2014/12/16/asd_crop_upscale_q85.jpg\" alt=\"Post img \" style=\"float:left;margin-right:10px\"/&gt; Lorem ipsum... &lt;br /&gt;";
    String textOnly = removeEntityEncodedHtmlTags(
            descriptionElementContent);
    System.out.println(textOnly);       
}

public static String removeEntityEncodedHtmlTags(String rawString) {
    Matcher tagMatcher = ENTITY_ENCODED_HTML_TAG.matcher(rawString);
    return tagMatcher.replaceAll("").trim();
}
只需通过
description
元素将上述代码中的
main
方法替换为您自己的循环即可


正则表达式模式
*?
表示“匹配序列
,然后匹配任何内容,直到第一次出现
”。此模式用于实例化单个静态
模式
对象,该对象可用于(反复)为传递给方法的每个原始字符串创建
匹配器
对象。然后,“<代码>匹配器”。ReopyAudio/Cult>方法只使用空字符串替换找到的每个匹配项(在原始字符串中),以从结果中删除它,只留下文本。

XML看起来不有效,因为它在文本内容中间有一个标记闭包<代码> />代码>。@ Arkanon对我来说是正确的。这是包含所有内容的链接:请参见说明部分。。我只需要查看链接到的页面的源代码,我仍然相信您的XML示例中存在错误。我想应该是
右边距:10px“/Lorem ipsum
这样
被编码为
。好的,正确,但无论如何我也可以解析它..问题是要解析的内容太多了!也许我做错了什么,但似乎不管用。。我将用您的代码建议编辑我的问题我想要的是只接受部分
Lorem ipsum或任何内容。模式是我确定的方式。但在您编辑的问题的代码中使用它可能是错误的。您正在调用
removeEntityEncodedHtmlTags
,并将结果分配给一个名为
textOnly
的变量,但您不使用
textOnly
执行任何操作。当然你想在地图中存储
textOnly
的值,而不是原始提取的值?不,我想我错了。你能把我的代码拿出来,告诉我怎么解吗?顺便说一下,变量textOnly我已经声明它是全局字符串变量
private static final Pattern ENTITY_ENCODED_HTML_TAG =
        Pattern.compile("&lt;.*?&gt;");

public static void main(String[] args) {
    String descriptionElementContent =
            "&lt;img src=\"http://images.website.it/thumbs/images/2014/12/16/asd_crop_upscale_q85.jpg\" alt=\"Post img \" style=\"float:left;margin-right:10px\"/&gt; Lorem ipsum... &lt;br /&gt;";
    String textOnly = removeEntityEncodedHtmlTags(
            descriptionElementContent);
    System.out.println(textOnly);       
}

public static String removeEntityEncodedHtmlTags(String rawString) {
    Matcher tagMatcher = ENTITY_ENCODED_HTML_TAG.matcher(rawString);
    return tagMatcher.replaceAll("").trim();
}