当前位置:  开发笔记 > 编程语言 > 正文

NamespaceContext并使用带有XPath的命名空间

如何解决《NamespaceContext并使用带有XPath的命名空间》经验,为你挑选了3个好方法。

解析包含Java中的命名空间的xpath似乎需要使用NamespaceContext对象,将前缀映射到命名空间URL,反之亦然.但是,NamespaceContext除了自己实现它之外,我找不到任何其他机制.这似乎违反直觉.

问题:是否有任何简单的方法NamespaceContext从文档中获取,或者创建一个或者失败,完全放弃前缀并指定具有完全限定名称的xpath?



1> McDowell..:

可以在不编写自己的类的情况下获取NamespaceContext实例.它的类使用页面显示您可以使用javax.xml.stream包获取一个.

String ctxtTemplate = "";
NamespaceContext nsContext = null;

XMLInputFactory factory = XMLInputFactory.newInstance();
XMLEventReader evtReader = factory
    .createXMLEventReader(new StringReader(ctxtTemplate));
while (evtReader.hasNext()) {
  XMLEvent event = evtReader.nextEvent();
  if (event.isStartElement()) {
    nsContext = ((StartElement) event)
        .getNamespaceContext();
    break;
  }
}

System.out.println(nsContext.getNamespaceURI(""));
System.out.println(nsContext.getNamespaceURI("foo"));
System.out.println(nsContext
    .getNamespaceURI(XMLConstants.XMLNS_ATTRIBUTE));
System.out.println(nsContext
    .getNamespaceURI(XMLConstants.XML_NS_PREFIX));

完全放弃前缀可能会导致表达式含糊不清 - 如果要删除名称空间前缀,则需要更改文档格式.从文档创建上下文不一定有意义.前缀必须与XPath表达式中使用的前缀匹配,而不是任何文档中的前缀,如下面的代码所示:

String xml = ""
    + ""
    + "hello"
    + ""
    + "";
String expression = "/stack:data/overflow:value";
class BaseFooContext implements NamespaceContext {
  @Override
  public String getNamespaceURI(String prefix) {
    if ("stack".equals(prefix))
      return "http://base";
    if ("overflow".equals(prefix))
      return "http://foo";
    throw new IllegalArgumentException(prefix);
  }

  @Override
  public String getPrefix(String namespaceURI) {
    throw new UnsupportedOperationException();
  }

  @Override
  public Iterator getPrefixes(
      String namespaceURI) {
    throw new UnsupportedOperationException();
  }
}
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
xpath.setNamespaceContext(new BaseFooContext());
String value = xpath.evaluate(expression,
    new InputSource(new StringReader(xml)));
System.out.println(value);

StAX API返回的实现和上面的实现都没有实现doc中定义的完整类/方法契约.您可以在此处获得完整的基于地图的实施.



2> Suppressingf..:

我自己一直在使用xpath和NamespaceContexts.我在developerworks上遇到了一个很好的处理问题.


在阅读了IBM的这篇文章后,我可以理解为什么没有默认实现.有多种方法可以解决这个问题.那说:为什么像Apache这样的开源组不会创建不同实现的库?

3> Asaf Mesika..:

我在名为NamespaceContextImpl的" Apache WebServices Common Utilities "中找到了一个方便的实现.

您可以使用以下maven依赖项来获取此类:


    org.apache.ws.commons
    ws-commons-util
    1.0.1

我以下面的方式使用它(我知道它是为sax构建的,但是在阅读完代码之后,它还可以):

NamespaceContextImpl nsContext = new NamespaceContextImpl();
nsContext.startPrefixMapping("foo", "my.name.space.com");

您不需要调用endPrefixMapping.

推荐阅读
帆侮听我悄悄说星星
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有