Kendi sınıfınızı yazmadan bir NamespaceContext örneğini almak mümkündür. class-use sayfasında, javax.xml.stream paketini kullanarak bir tane alabilirsiniz.
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 önekleri tamamen belirsiz ifadeler yol açması muhtemeldir - Eğer ad önekleri düşmesi istiyorsanız, belge biçimini değiştirmek gerekiyordu. Bir belgeden bir bağlam oluşturmak, mutlaka mantıklı değildir. önekler bu kodda olduğu gibi, XPath ifadesinde kullanılan olanlar, herhangi bir belgede olanları değil eşleşmesi gerekir:
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);
Ne STAX API ne de yukarıdaki biri tarafından döndürülen uygulama tam class/method uygulamak dokümanda tanımlanan sözleşmeler. Tam, harita tabanlı bir uygulama here alabilirsiniz.
Sorunuzdaki bazı basit yanlışlıklar var: Xath ile tüm ad alanlarını XPath ile alabilirsiniz (bunun için SO yanıtları vardır), ancak basit bir önek ad alanı URI'sini sınıflandıramazsınız çünkü * * Her düğüm için ** farklı bir sınır olabilir. Düğümleri seçerken, önceden istediğiniz elemanların isimlerini bilmelisiniz ** ve bunların isimlerini içeren URI ** –