Java中使用XPath获取XML子节点值出现重复该如何解决?
问题原因
你当前使用的XPath表达式/url-mappings/url-mapping/request-handler-class/text()是绝对路径,以/开头的XPath会从整个XML文档的根节点开始匹配,所以每次查询都会返回文档中第一个符合条件的节点值,这就是两次都输出com.mappingtool.rh.Screen1RH的原因。
解决方案
有两种常用修改方式,任选其一即可:
方案1:使用相对路径查询(更推荐)
既然你循环里已经拿到了当前的url-mapping节点,直接用相对路径查询该节点下的子节点即可,不需要写全文档的绝对路径:
把循环里的XPath编译语句改成:
XPathExpression expr = xpath.compile("request-handler-class/text()");
相对路径不需要以/开头,会从你传入evaluate方法的当前节点开始匹配,每次都会取当前url-mapping下的request-handler-class值。
方案2:修正带索引的绝对路径写法
你注释掉的带索引的写法思路是对的,但要注意XPath的节点索引是从1开始计数的,你的循环变量x是从0开始,所以要加1偏移:
XPathExpression expr = xpath.compile("/url-mappings/url-mapping["+ (x+1) +"]/request-handler-class/text()");
这种方式不需要依赖当前循环的节点,直接通过索引定位全文档的对应节点,也可以得到正确结果。
修改后完整可运行代码
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; import java.io.File; import org.w3c.dom.Document; import org.w3c.dom.NodeList; public class MappingTool { public static void main(String[] args) throws Exception { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); Document document = db.parse(new File("src/com/mappingtool/requestmapping.xml")); NodeList nodeList = document.getElementsByTagName("url-mapping"); XPath xpath = XPathFactory.newInstance().newXPath(); for(int x=0,size= nodeList.getLength(); x<size; x++) { System.out.println(nodeList.item(x).getAttributes().getNamedItem("url").getNodeValue()); // 使用相对路径的方案 XPathExpression expr = xpath.compile("request-handler-class/text()"); String rhClass = (String)expr.evaluate(nodeList.item(x), XPathConstants.STRING); System.out.println(rhClass); } } }
运行后即可得到你期望的输出。
内容的提问来源于stack exchange,提问作者Sun
相关产品推荐
相关产品推荐

