当前位置: 首页 > 面试题库 >

NamespaceContext并在XPath中使用名称空间

阎星华
2023-03-14
问题内容

解决在Java中包含名称空间的xpath似乎需要使用一个NamespaceContext对象,将前缀映射到名称空间url,反之亦然。但是,NamespaceContext除了自己实现之外,我找不到其他机制。这似乎违反直觉。

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


问题答案:

无需编写自己的类就可以获取 NamespaceContext
实例。它的类使用页面显示您可以使用javax.xml.stream包获得其中一个。

String ctxtTemplate = "<data xmlns=\"http://base\" xmlns:foo=\"http://foo\" />";
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 = "<data xmlns=\"http://base\" xmlns:foo=\"http://foo\" >"
    + "<foo:value>"
    + "hello"
    + "</foo:value>"
    + "</data>";
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<String> 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返回的实现或以上方法均未实现文档中定义的完整类
/
方法协定。您可以在此处获得基于地图的完整实现。



 类似资料:
  • 问题内容: 我有以下格式的xml文档: 我需要使用lxml中的xpath检索所有元素。我的问题是我不知道如何使用空的名称空间。我尝试了以下示例,但没有用。请指教。 我尝试过的各种方法是: 要么 要么 在这一点上,我只是不知道该尝试什么。任何帮助是极大的赞赏。 问题答案: 这样的事情应该起作用: 另请参见http://lxml.de/xpathxslt.html#namespaces-and- pr

  • 问题内容: 我正在尝试解析Java中的SOAP请求,但代码未返回任何节点,这里的代码可以使任何人找到错误 问题答案: 您需要设置一个上: 演示版 输出量

  • 问题内容: 当我的XML看起来像这样(no )时,我可以使用XPath轻松查询它 但是当看起来像这样我就不能 有任何想法吗? 问题答案: 在第二个示例XML文件中,元素绑定到名称空间。你的XPath尝试处理绑定到默认“无名称空间”名称空间的元素,因此它们不匹配。 首选方法是使用名称空间前缀注册名称空间。它使你的XPath更加易于开发,读取和维护。 但是,并不一定要注册名称空间并在XPath中使用名

  • 我正在尝试选择一个特定的

  • 问题内容: 您可以帮助我调整此代码,以便它成功解析XML吗?如果删除XML名称空间,它将起作用: 问题答案: 您必须在XPath中使用前缀,例如:“ / my:foo / my:bar”您可以选择任何喜欢的前缀-它与您在XML中使用或不使用的前缀无关。文件-但您必须选择一个。这是XPath 1.0的限制。 您必须执行从“我”到“ http://foo.bar/boo ”的前缀映射(而不是“ htt

  • 问题内容: 我想获取标记之间的所有内容,但是由于urn:名称空间,我不知道该怎么做。 有任何想法吗? 问题答案: 简短的答案:使用XPath 。这样:将返回 或者,您可以实现一个映射名称空间名称和URI的,并在查询之前在XPath对象上对其进行设置。 看一下这篇博客文章, 更新: 该文章已结束,您可以在webarchive上看到它 解决方案1样本: 解决方案2样本: 编辑 这是一个完整的示例,它可