Java读取不带前缀但在命名空间范围内的xml元素

Java读取不带前缀但在命名空间范围内的xml元素,java,web-services,soap,axis2,Java,Web Services,Soap,Axis2,从功能上讲,这两个块应该是相同的 <soapenv:Body> <ns1:login xmlns:ns1="urn:soap.sof.com"> <userInfo> <username>superuser</username> <password>qapass</password> </userInfo> </ns1:login> <

从功能上讲,这两个块应该是相同的

<soapenv:Body>
  <ns1:login xmlns:ns1="urn:soap.sof.com">
    <userInfo>
      <username>superuser</username>
      <password>qapass</password>
    </userInfo>
  </ns1:login>
</soapenv:Body>

-----------------------

<soapenv:Body>
  <ns1:login xmlns:ns1="urn:soap.sof.com">
    <ns1:userInfo>
      <ns1:username>superuser</ns1:username>
      <ns1:password>qapass</ns1:password>
    </ns1:userInfo>
  </ns1:login>
</soapenv:Body>

因此,如果我将第二个getElementsByTagnames替换为((元素)项).getElementsByTagName(“用户名”);,我能够获得username元素。即使用户名没有前缀,它也没有ns1名称空间吗?我是否应该跟踪名称空间范围以读取元素?如果我的xml元素是多层次的,这不是很糟糕吗?是否有一种变通方法,可以在不知道是否定义了前缀的情况下读取ns1命名空间中的元素

简而言之,答案是否定的,这些文件不一样。元素不会继承名称空间,在设置前缀时,名称空间不再作为文档的默认名称空间

这两者是相同的:

<soapenv:Body>
  <login xmlns="urn:soap.sof.com">
    <userInfo>
      <username>superuser</username>
      <password>qapass</password>
    </userInfo>
  </login>
</soapenv:Body>

-----------------------

<soapenv:Body>
  <ns1:login xmlns:ns1="urn:soap.sof.com">
    <ns1:userInfo>
      <ns1:username>superuser</ns1:username>
      <ns1:password>qapass</ns1:password>
    </ns1:userInfo>
  </ns1:login>
</soapenv:Body>
我已经很久没有使用JAXP了,但我认为这基本上是正确的。运行xPath并不慢,但编译它们却很慢。为了提高性能,您可以将它们编译为XPathExpression,但它们不是线程安全的,所以您不能将它们缓存在servlet上。从来都不容易


如果您正在处理大量XML,我建议使用Jaxen而不是JAXP。(另一方面,如果您很少使用XML,而它只是前端的一种XML,那么可能getElementsByTagName并不是最糟糕的事情:)

根据本文,名称空间是由元素继承的。此外,上部SOAP主体由AXIS2存根(由AXIS2的wsdl2java创建)生成。所有复杂类型都在urn:soap.sof.com目标命名空间中定义。如果名称空间由元素继承,AXIS就不会创建没有前缀的元素,我错了吗?前缀ns1在范围内,但没有前缀的元素在默认名称空间中,而不是在其父名称空间中,并且没有声明默认名称空间。您能给我看一些使用XPath的示例代码吗?与使用getElementByTag相比,它会慢很多吗?
<soapenv:Body>
  <login xmlns="urn:soap.sof.com">
    <userInfo>
      <username>superuser</username>
      <password>qapass</password>
    </userInfo>
  </login>
</soapenv:Body>

-----------------------

<soapenv:Body>
  <ns1:login xmlns:ns1="urn:soap.sof.com">
    <ns1:userInfo>
      <ns1:username>superuser</ns1:username>
      <ns1:password>qapass</ns1:password>
    </ns1:userInfo>
  </ns1:login>
</soapenv:Body>
private NamespaceContext ns = new NamespaceContext() {
public String getNamespaceURI(String prefix) {
if (prefix.equals("urn") return "urn:soap.sof.com";
else return XMLConstants.NULL_NS_URI;
}
public String getPrefix(String namespace) {
throw new UnsupportedOperationException();
}
public Iterator getPrefixes(String namespace) {
throw new UnsupportedOperationException();
}};

XPathFactory xpfactory = XPathFactory.newInstance();
XPath xpath = xpfactory.newXPath();
xpath.setNamespaceContext(ns);
NodeList nodes = (NodeList) xpath.evaluate("//urn:userInfo|//userInfo", myDom, XPathConstants.NODESET);
//find all userInfo at any depth with either namespace.