我的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标签可以在较低或较高的位置。
有什么更好的方法呢?我是否必须使用一些String操作或Regex或XML解析器来执行此操作?
我对此问题附有一个小查询。如果我需要
之间的数据<Record> </Record>
即
<op>Add</op><sensdata>4001887XXXXX</sensdata><id>4</id><a1>1111201090467034</a1>
我可以使用xml解析器吗?我能够得到像Add4001887XXXXX41111201090467034这样的值。但不是标签。
答案 0 :(得分:2)
您还可以使用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);
答案 1 :(得分: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);
答案 2 :(得分:0)
如果您不想使用任何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 :(得分:0)
试试这个
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);
答案 4 :(得分:-1)
我认为有两种方法:如果此任务不太可能发生变化,一个简单的正则表达式可以为您和一行代码解决它。如果问题变得结构化,或者你的应用程序使用了大量的xml,你可能想要解析它并动态运行。
一个简单的正则表达式可能是:
".*<[sS]ensdata>(.*)</[sS]ensdata>.*", group 1 ( "$1" ) will be your value.