NamespaceContext и пространства имен использования с XPath

В документации к конструктору Cache говорится, что это только для внутреннего использования. Чтобы получить объект Cache, вызовите HttpRuntime.Cache, а не создавайте экземпляр с помощью конструктора.

15
задан jszumski 27 April 2013 в 17:14
поделиться

2 ответа

It is possible to get a NamespaceContext instance without writing your own class. Its class-use page shows you can get one using the javax.xml.stream package.

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));

Forgoing prefixes altogether is likely to lead to ambiguous expressions - if you want to drop namespace prefixes, you'd need to change the document format. Creating a context from a document doesn't necessarily make sense. The prefixes have to match the ones used in the XPath expression, not the ones in any document, as in this code:

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);

Neither the implementation returned by the StAX API nor the one above implement the full class/method contracts as defined in the doc. You can get a full, map-based implementation here.

12
ответ дан 1 December 2019 в 02:29
поделиться

Я только что сам работал над использованием xpath и NamespaceContexts. Я нашел хорошее решение проблемы на сайте developerworks .

8
ответ дан 1 December 2019 в 02:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: