首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java Xpath NameSpace解析

Java Xpath NameSpace解析
EN

Stack Overflow用户
提问于 2014-01-17 21:11:22
回答 1查看 301关注 0票数 2

尽管我看到了类似的帖子,但我似乎无法解决这个问题(所以我手动解析xml,而不是使用xpath表达式)……这是我拥有的XML ...

代码语言:javascript
复制
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:tnew="http://PR_Library/TNeWebService">
   <soapenv:Header/>
   <soapenv:Body>
      <tnew:ApercuenRequest>
         <tnew:OpcionCarga>0</tnew:OpcionCarga>
         <tnew:Sucursal>1</tnew:Sucursal>
         <tnew:Vendedor>8000</tnew:Vendedor>
         <tnew:CanalConsulta>1</tnew:CanalConsulta>
         <tnew:UsuarioCarga>8000</tnew:UsuarioCarga>
         <tnew:Comercio>0</tnew:Comercio>
         <tnew:FechaEvaluacion>20140109</tnew:FechaEvaluacion>
         <tnew:ModeloDeEvaluacion></tnew:ModeloDeEvaluacion> 
         <tnew:IdEvaluacion>3694852</tnew:IdEvaluacion>
         <tnew:Dudosa>0</tnew:Dudosa>
         <tnew:Exceptuado>1</tnew:Exceptuado>
         <tnew:TipoDocumento>1</tnew:TipoDocumento>
         <tnew:NumeroDocumento>5881040</tnew:NumeroDocumento>
         <tnew:Sexo>F</tnew:Sexo>
         <tnew:Rol>5</tnew:Rol>
         <tnew:RelacionLaboral>5</tnew:RelacionLaboral>
         <tnew:TipoEmpleado>0</tnew:TipoEmpleado>
         <tnew:FechaIngresoEmpleo></tnew:FechaIngresoEmpleo>
         <tnew:AntiguedadLaboral>0</tnew:AntiguedadLaboral>
         <tnew:IngresoMensualAnalista>0</tnew:IngresoMensualAnalista>
         <tnew:IngresoMensual>6000</tnew:IngresoMensual>
         <tnew:EstadoCivil>4</tnew:EstadoCivil>
         <tnew:FechaDeNacimiento>19540423</tnew:FechaDeNacimiento>
         <tnew:SituacionVivienda>3</tnew:SituacionVivienda>
         <tnew:DomicilioProvincia></tnew:DomicilioProvincia>
         <tnew:DomicilioLocalidad></tnew:DomicilioLocalidad>
         <tnew:NivelEstudios></tnew:NivelEstudios>
         <tnew:RelacionConTN>1</tnew:RelacionConTN>
         <tnew:FechaAltaAbogado></tnew:FechaAltaAbogado>
         <tnew:MarcaAbogado>N</tnew:MarcaAbogado>
         <tnew:Cdi></tnew:Cdi>
         <tnew:Campana></tnew:Campana>
        </tnew:ApercuenRequest>
   </soapenv:Body>
</soapenv:Envelope>

以及下面的Java代码...

代码语言:javascript
复制
private XPathFactory xpathFactory = null;  
private XPath xpath = null; 
private DocumentBuilderFactory factory = null; 
private DocumentBuilder builder= null;                                              
private XPathExpression expr;
private Node nodo = null;
private Node nodoAux = null;
private NodeList result = null;
private NodeList nodeList = null;

...

            try {
            xpathFactory = XPathFactory.newInstance();
            xpath = xpathFactory.newXPath();
            factory = DocumentBuilderFactory.newInstance();
            builder= factory.newDocumentBuilder();

            NamespaceContext context = new NameSpaceNevada();
            xpath.setNamespaceContext(context);
        }
        catch (Exception e) {

        }  

...

evaluarExpresion(documentoXML,"/soapenv:Envelope/soapenv:Body/tnew:ApercuenRequest/tnew:OpcionCarga")

    private String evaluarExpresion(Document documentoXML, String expresion) throws Exception{
    try {
        expr = xpath.compile(expresion);
        result = (NodeList)expr.evaluate(documentoXML, XPathConstants.NODESET);
        System.out.println((result.item(0)!=null?result.item(0).getNodeName():"") + " ->>>> " + (result.item(0).getFirstChild()!=null?result.item(0).getFirstChild().getNodeValue():""));
        return result.item(0).getFirstChild()!=null?result.item(0).getFirstChild().getNodeValue():null;
    }
    catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

而且我似乎无法获得您在XML中看到的"0“值……我试过很多东西...我会看着..。问题是,我可以手动解析它,但笑话是通过xpath表达式来实现的,这样我就可以节省代码……

希望我让你明白了..。

来自NameSpaceNevada对象的getNamespaceURI方法如下所示:

代码语言:javascript
复制
public String getNamespaceURI(String prefix) {
  if (prefix == null) {
    throw new IllegalArgumentException("No prefix provided!");
  } else if (prefix.equals(XMLConstants.DEFAULT_NS_PREFIX)) {
    return "http://univNaSpResolver/book";
  } else if (prefix.equals("soapenv")) {
    return "http://schemas.xmlsoap.org/soap/envelope/";
  } else if (prefix.equals("tnew")) {
    return "http://PR_Library/TNeWebService";
  } else {
    return XMLConstants.NULL_NS_URI;
  }
}
EN

回答 1

Stack Overflow用户

发布于 2014-01-17 22:15:43

不必将表达式作为节点集求值,然后执行复杂的DOM操作来提取文本值,您可以首先将表达式作为字符串进行求值。

代码语言:javascript
复制
expr.evaluate(documentoXML);

将计算表达式并使用XPath规则将结果转换为字符串,在本例中,字符串将为您提供第一个(实际上是惟一的) tnew:OpcionCarga元素的文本内容。

但它不起作用的真正原因是,缺省情况下,Java的DocumentBuilderFactory是非名称空间感知的(在许多人看来,这是一个非常糟糕的设计决策,但现在如果不破坏向后兼容性就无法纠正它)-您必须这样做

代码语言:javascript
复制
factory.setNamespaceAware(true);

在调用.newDocumentBuilder()以创建支持名称空间的解析器之前。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21186888

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档