вопрос про xpath и namespace

pitrik2

имеется XML

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ASKResponse xmlns="http://tempuri.org/">
<ASKResult>ляляля</ASKResult>
</ASKResponse>
</soap:Body>
</soap:Envelope>

/soap:Envelope/soap:Body/ASKResponse/ASKResult/text не работает
/soap:Envelope/soap:Body - это работает
/soap:Envelope/soap:Body/ASKResponse - а это нет
/soap:Envelope/soap:Body/:ASKResponse/:ASKResult/text - тоже не работает
все видимо из-за того что в описании ASKResponse не указан префикс для namespace
это неправильный XML или нужно какое-то хитрое xpath выражение составить?
P.S.
вызываю xpath на джаве: XPathAPI.eval(doc, expression, prefixResolver)
в гугле нашел другое решение:

NamespaceContext ctx = new NamespaceContext {
public String getNamespaceURI(String prefix) {
return prefixResolver.getNamespaceForPrefix(prefix);
}
}
XPath xpath = xpathFact.newXPath;
xpath.setNamespaceContext(ctx);
xpath.evaluate(expression, doc);

так тоже не работает
но для этого решения нашел идиотский воркэраунд:

public String getNamespaceURI(String prefix) {
if(prefix.equals("lala"
return "http://tempuri.org/";
return prefixResolver.getNamespaceForPrefix(prefix);
}

и тогда /soap:Envelope/soap:Body/lala:ASKResponse/lala:ASKResult/text работает !

6yrop

но для этого решения нашел идиотский воркэраунд:
мне тоже показалось это странным. В .NET похожая ситуация
 
If the XPath expression does not include a prefix, it is assumed that the namespace URI is the empty namespace. If your XML includes a default namespace, you must still add a prefix and namespace URI to the XmlNamespaceManager; otherwise, you will not get any nodes selected. For more information, see Select Nodes Using XPath Navigation.
http://msdn2.microsoft.com/en-us/library/system.xml.xmlnode....
  

P.S. все-таки MSDN это круто

conv3rsje

Это проблема XPath и XSLT. Сам с ней бился и плевался.
Можно (но геморройно) писать вот такие xpath (кусок из хслт для XHTML) запросы

<xsl:template match='*[namespace-uri = "http://www.w3.org/1999/xhtml" and local-name = "body"]'>

ЗЫ
Это все, если не хочется добавлять свой namespace в XPath. Если это не в напряг - то просто добавляется
нужный xmlns и запрос будет выглядить приблизительно так

// добавить xmlns:some-ns="http://tempuri.org/"
/soap:Envelope/soap:Body/some-ns:ASKResponse/some-ns:ASKResult/text

pitrik2

<xsl:template match='*[namespace-uri = "http://www.w3.org/1999/xhtml" and local-name = "body"]'>
о
спасибки
это помогло понять общую картину
Оставить комментарий
Имя или ник:
Комментарий: