获取一个字符串的元素,它看起来像 XML 并在 java 中对其进行操作

Posted

技术标签:

【中文标题】获取一个字符串的元素,它看起来像 XML 并在 java 中对其进行操作【英文标题】:Get an element of a String, which looks like XML and manipulate it in java 【发布时间】:2014-11-06 16:57:32 【问题描述】:

我的 java String 对象中有一个 XML 字符串,如下所示:

<Record><op>Add</op><sensdata>400188711111</sensdata><id>4</id><a1>1111201090467034</a1></Record>

我需要获取 sensdata 标签之间的数据并将其屏蔽为 4001887XXXXX 之类的内容,并准备如下 xml 字符串并记录它。

<Record><op>Add</op><sensdata>4001887XXXXX</sensdata><id>4</id><a1>1111201090467034</a1></Record>

sensdata标签可以在lower或者upper。

什么是更好的方法?我是否必须使用一些字符串操作或正则表达式或 XML 解析器来完成它?

我有一个关于这个问题的小问题。如果我需要

之间的数据
<Record> </Record>

<op>Add</op><sensdata>4001887XXXXX</sensdata><id>4</id><a1>1111201090467034</a1>

我可以使用 xml 解析器吗?我能够得到像 Add4001887XXXXX41111201090467034 这样的值。但不带标签。

【问题讨论】:

它是 XML - 所以使用 XML 解析器。 使用 Xpath 表达式获取值,然后使用 DOM 库附加到 XML。 请don't use regular expressions. @JonSkeet 他将如何使用解析器编写代码? @Aeshang:有多种方法...我建议OP自己尝试,如果遇到困难,请提出具体问题。 【参考方案1】:

由于您的字符串包含 XML,您应该使用 XML 解析器。一个合适的例子可以在here 找到。最重要的是,您的问题的适当解决方案是:

ByteArrayInputStream stream = new ByteArrayInputStream("<Record><op>Add</op><sensdata>400188711111</sensdata><id>4</id><a1>1111201090467034</a1></Record>".getBytes());
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(stream);

NodeList sensdata = document.getDocumentElement().getElementsByTagName("sensdata");

现在您有了sensdata 的节点列表。您可以进一步操作它。要使用给定节点的字符串值,您可以执行以下操作:

String sensData = sensdata.item(0).getTextContent();

可能建议在这种情况下编写防御性代码,以避免 NPE,因此,应注意上述解决方案:

if (sensdata.getLength() > 0) 
   String sensData = sensdata.item(0).getTextContent();        

正如在其他答案中所指出的,也可以使用 XPath:

XPath xPath = XPathFactory.newInstance().newXPath();
String data = xPath.compile("/Record/sensdata").evaluate(document);

【讨论】:

感谢大家的大力帮助。我使用了 xml 解析,它对我有用。 @Anita 很高兴能帮上忙!【参考方案2】:

这是如果您不想使用任何 XML 解析器。

您可以在尝试查找 sensdata 之前使用 toLowerCase()。不要使用原始字符串来保留区分大小写的数据,使用复制的字符串。然后使用相同的索引来操作原始字符串。

例子

int startIndex = yourCopiedString.toLowerCase().indexOf("<sensdata>")+10;
int endIndex = yourCopiedString.toLowerCase().indexOf("</sensdata>");
String dataPart = yourCopiedString.substring(startIndex, endIndex);

用于替换:

String newEncodedString =  yourOriginalString.replace(yourOriginalString.substring(startIndex,endIndex), "XXXXXXXX");

如果给定子字符串有重复,那么试试这个。

String newEncodedString = yourOriginalString.substring(0,startIndex)+ "XXXXXXXX"+yourOriginalString.substring(endIndex,yourOriginalString.lenght);

【讨论】:

【参考方案3】:

我认为有两种方法:如果这个任务不太可能改变,一个简单的正则表达式可以为你解决它和一行代码。如果问题变得结构化,或者您的应用使用大量 xml,您可能希望对其进行解析并动态操作。

一个简单的正则表达式可以是:

".*<[sS]ensdata>(.*)</[sS]ensdata>.*", group 1 ( "$1" ) will be your value.

【讨论】:

【参考方案4】:

试试这个

String str = "<Record><op>Add</op><sensdata>400188711111</sensdata><id>4</id><a1>1111201090467034</a1></Record>"

int start = str.indexOf("<sensdata>");
int end = str.indexOf("</sensdata>");
String sendDataVal = str.substring(start+10, end);

【讨论】:

【参考方案5】:

您还可以使用 XPath 表达式来获取所需的数据。

因此,解决方案可能是:

    String xml = "<Record><op>Add</op><sensdata>400188711111</sensdata><id>4</id>"
            + "<a1>1111201090467034</a1></Record>";
    DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = null;
    try 
        builder = builderFactory.newDocumentBuilder();
     catch (ParserConfigurationException e) 
        e.printStackTrace();  
    
    Document document = builder.parse(new ByteArrayInputStream(xml.getBytes()));
    XPath xPath =  XPathFactory.newInstance().newXPath();
    String data = xPath.compile("/Record/sensdata").evaluate(document);
    System.out.println(data);

【讨论】:

以上是关于获取一个字符串的元素,它看起来像 XML 并在 java 中对其进行操作的主要内容,如果未能解决你的问题,请参考以下文章

序列化时带有特殊字符的 XML 元素名称

XSLT 获取最后一个元素

如何使用 xslt 获取与复杂条件匹配的所有 xml 项的计数并在终止语句中使用它?

合并相同类型的 xml 节点并在 C# 中显示两个结果

组合两个函数时显示错误(元素重复)

如何在解析后获取xml文件的元素并在iPhone程序中对其进行验证