下面的方法查找property
文档中的所有元素,并使用 XPath 收集value
那些命名为value
wihtout 的元素的所有子元素。
private static List<Element> getValueElements(Document document) {
List<Element> result = new ArrayList<Element>();
NodeList propertyElements = document.getElementsByTagName("property");
for (int i = 0, ilen = propertyElements.getLength(); i < ilen; i++) {
Node propertyNode = propertyElements.item(i);
if (!(propertyNode instanceof Element))
continue;
NodeList children = ((Element) propertyNode).getChildNodes();
for (int j = 0, jlen = children.getLength(); j < jlen; j++) {
Node child = children.item(j);
if (!(child instanceof Element) || !"value".equals(child.getNodeName()))
continue;
result.add((Element) child);
}
}
return result;
}
但是您可以使用 XPath 表达式以更优雅的方式执行相同的操作//property/value
:
private static List<Element> getValueElementsUsingXpath(Document document) throws XPathExpressionException {
XPath xpath = XPathFactory.newInstance().newXPath();
// XPath Query for showing all nodes value
XPathExpression expr = xpath.compile("//property/value");
Object xpathResult = expr.evaluate(document, XPathConstants.NODESET);
List<Element> result = new ArrayList<Element>();
NodeList nodes = (NodeList) xpathResult;
for (int i = 0; i < nodes.getLength(); i++) {
Node valueNode = nodes.item(i);
if (!(valueNode instanceof Element)) continue;
result.add((Element) valueNode);
}
return result;
}
您可以像这样使用上面的方法:
public static void main(String[] args) throws Exception {
Document doc = parseDocument("properties.xml");
List<Element> valueElements = getValueElements(doc); // or getValueElementsUsingXpath(doc)
int nodeNumber = 0;
for (Element element : valueElements) {
nodeNumber++;
System.out.println("Node " + nodeNumber + ": " + formatValueElement(element));
}
}
private static String formatValueElement(Element element) {
StringBuffer result = new StringBuffer();
boolean first = true;
NodeList children = ((Element) element).getChildNodes();
for (int i = 0, len = children.getLength(); i < len; i++) {
Node child = children.item(i);
String childText = null;
switch (child.getNodeType()) {
case Node.CDATA_SECTION_NODE:
case Node.TEXT_NODE:
childText = child.getTextContent().trim();
}
if (childText == null || childText.isEmpty()) {
continue;
}
if (first)
first = false;
else
result.append(" ");
result.append(childText);
}
return result.toString();
}
我使用以下两个 XML 输入对其进行了测试,因为您的 XML 缺少结束</property>
标记。
这是第一个(我添加了额外的元素,以表明它们没有找到):
<rootNode>
<property regex=".*" xpath=".*">
<value>
127.0.0.1
</value>
<anythingElse>Text here</anythingElse>
</property>
<anythingElse>Text here</anythingElse>
<property regex=".*" xpath=".*">
<value>
val <![CDATA[
<Valve className="org.tomcat.AccessLogValve" exclude="PASSWORD,pwd,pWord,ticket" enabled="true" serviceName="zohocrm" logDir="../logs" fileName="access" format="URI,"PARAM","REFERRER",TIME_TAKEN,BYTES_OUT,STATUS,TIMESTAMP,METHOD,SESSION_ID,REMOTE_IP,"INTERNAL_IP","USER_AGENT",PROTOCOL,SERVER_NAME,SERVER_PORT,BYTES_IN,ZUID,TICKET_DIGEST,THREAD_ID,REQ_ID"/>
]]> test
</value>
</property>
</rootNode>
第二个有嵌套的属性元素(我在最后添加了缺少的元素):
<property regex=".*" xpath=".*">
<value>
127.0.0.1
</value>
<property regex=".*" xpath=".*">
<value>
val <![CDATA[
<Valve className="org.tomcat.AccessLogValve" exclude="PASSWORD,pwd,pWord,ticket" enabled="true" serviceName="zohocrm" logDir="../logs" fileName="access" format="URI,"PARAM","REFERRER",TIME_TAKEN,BYTES_OUT,STATUS,TIMESTAMP,METHOD,SESSION_ID,REMOTE_IP,"INTERNAL_IP","USER_AGENT",PROTOCOL,SERVER_NAME,SERVER_PORT,BYTES_IN,ZUID,TICKET_DIGEST,THREAD_ID,REQ_ID"/>
]]> test
</value>
</property>
</property>