Java 使用已编译的XPATH表达式解析XML文件时出现问题?

Java 使用已编译的XPATH表达式解析XML文件时出现问题?,java,xml,xpath,xml-parsing,Java,Xml,Xpath,Xml Parsing,我当时正在处理一个我认为可以解决的问题。我希望有人能帮我写这段代码。我过不了这一关。如果我使用XPATH表达式“//*/text()”,我在下面共享的代码将匹配,但如果我使用更具体的表达式并使用“//tag0:G/text()”,它将无法匹配。知道我做错了什么吗?我只是想从下面提供的XML中获取2“tag0:G”值: import java.io.IOException; import java.io.StringReader; import javax.xml.parsers.Docu

我当时正在处理一个我认为可以解决的问题。我希望有人能帮我写这段代码。我过不了这一关。如果我使用XPATH表达式“//*/text()”,我在下面共享的代码将匹配,但如果我使用更具体的表达式并使用“//tag0:G/text()”,它将无法匹配。知道我做错了什么吗?我只是想从下面提供的XML中获取2“tag0:G”值:

import java.io.IOException;
import java.io.StringReader;    
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;    
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;    
public class Test1 {        
  public static void main(String[] args) {
    System.out.println("Test start...");
    String myXML = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" +
    "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
    "<soapenv:Body>" +
    "<tag0:getA xmlns:tag0=\"http://me.ws.ix\">" +
    "<tag0:B>" +
    "<tag0:CC>" +
    "<tag0:CC>" +
    "<tag0:D>false</tag0:D>" +
    "<tag0:E>false</tag0:E>" +
    "<tag0:F xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"/>" +
    "<tag0:G>10001</tag0:G>" +
    "<tag0:H>7744000002</tag0:H>" +
    "</tag0:CC>" +
    "<tag0:CC>" +
    "<tag0:D>false</tag0:D>" +
    "<tag0:E>false</tag0:E>" +
    "<tag0:F xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\"/>" +
    "<tag0:G>20002</tag0:G>" +
    "<tag0:H>1111122222</tag0:H>" +
    "</tag0:CC>" +
    "</tag0:CC>" +
    "<tag0:I>2012-05-27 23:38:48</tag0:I>" +
    "</tag0:B>" +
    "</tag0:getA>" +
    "</soapenv:Body>" +
    "</soapenv:Envelope>";

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    factory.setNamespaceAware(true);
    Document doc = null;
    NodeList nodes = null;
    try {           
      doc = factory.newDocumentBuilder().parse( new InputSource( new StringReader( myXML) ) );
      XPathExpression expr = XPathFactory.newInstance().newXPath()
        .compile("//tag0:G/text()"); // this fails, I don't know why
      nodes = (NodeList)expr.evaluate(doc, XPathConstants.NODESET);
    } catch (SAXException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (ParserConfigurationException e) {
      e.printStackTrace();
    } catch (XPathExpressionException e) {
      e.printStackTrace();
    }
    System.out.println("Nodes length: " + nodes.getLength() );
    for (int i = 0; i < nodes.getLength(); i++) { 
      String val = nodes.item(i).getNodeValue(); 
      System.out.println( "Val: " + val ); 
    }
    System.out.println("Test end...");
  }    
}
import java.io.IOException;
导入java.io.StringReader;
导入javax.xml.parsers.DocumentBuilderFactory;
导入javax.xml.parsers.parserConfiguration异常;
导入javax.xml.xpath.XPathConstants;
导入javax.xml.xpath.XPathExpression;
导入javax.xml.xpath.XPathExpressionException;
导入javax.xml.xpath.XPathFactory;
导入org.w3c.dom.Document;
导入org.w3c.dom.NodeList;
导入org.xml.sax.InputSource;
导入org.xml.sax.SAXException;
公共类Test1{
公共静态void main(字符串[]args){
System.out.println(“测试启动…”);
字符串myXML=“”+
"" +
"" +
"" +
"" +
"" +
"" +
“假”+
“假”+
"" +
"10001" +
"7744000002" +
"" +
"" +
“假”+
“假”+
"" +
"20002" +
"1111122222" +
"" +
"" +
"2012-05-27 23:38:48" +
"" +
"" +
"" +
"";
DocumentBuilderFactory工厂=DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
单据单据=空;
NodeList节点=null;
试试{
doc=factory.newDocumentBuilder().parse(新的InputSource(新的StringReader(myXML));
XPathExpression expr=XPathFactory.newInstance().newXPath()
.compile(“//tag0:G/text()”;//这失败了,我不知道为什么
nodes=(NodeList)expr.evaluate(doc,XPathConstants.NODESET);
}捕获(SAXE异常){
e、 printStackTrace();
}捕获(IOE异常){
e、 printStackTrace();
}捕获(ParserConfiguration异常e){
e、 printStackTrace();
}捕获(XPathExpressionException e){
e、 printStackTrace();
}
System.out.println(“节点长度:+Nodes.getLength());
对于(inti=0;i
在编译XPath表达式之前,应该在
XPath
实例上注册一个。你可以用它来做

请在xml.apache.org上阅读

其思想是,当使用名称空间信息解析文档时,XPath执行器需要知道如何将正在使用的前缀与运行它的文档中的名称空间URI相匹配。前缀本身什么也不说,您可以使用任意前缀,只要它映射到相同的URI


p、 当然,你也可以作弊——如果每次出现的“G”(或你所追求的任何元素)都来自同一个名称空间——你可以简单地这么做

//*[local-name()='G'] 

然而,虽然这是可行的,但这只是回避了这个问题。您不妨咬紧牙关,跨越名称空间……

提供的信息不足,无法回答问题。怎么会失败?”更具体的“比如什么?”我提供了一个完整的代码片段来演示这个问题。这怎么不够?如果运行代码,您会注意到没有堆栈跟踪。这个问题不是关于错误,而是关于xpath与我期望它匹配的内容不匹配。@djangofan希望人们运行您的代码,这是非常乐观的。你应该提供足够的细节,以便有足够经验的读者能够看到问题。如果某件事情失败了,你应该说明它是如何失败的。当我们诊断问题时,我们首先看到的是错误消息(或者如果结果不正确,我们会看到不正确的结果。)向下投票。好的,我明白你的意思。我还在学习。谢谢为什么通配符表达式可以工作呢?这让我很扫兴,这不一样。通过使DOM工厂名称空间具有感知性,可以确保解析将保留名称空间信息。现在还需要告诉XPath前缀的含义。请遵循我提供的链接,它应该开始变得更有意义。如果你还有,请告诉我questions@djangofan,我们每天都在学习。通配符之所以有效,是因为XPath中的
*
匹配任何元素。它不太关心元素的实际名称空间,因为它对于
*
表达式来说与其他任何名称空间一样好。结果证明它非常简单,而且现在很有意义。很高兴终于大致了解了XML名称空间(至少我认为我了解)。