JXPath для фильтрации сообщений SOAP

Я пытаюсь извлечь значение узла GoodEmail из ответа SOAP. Кажется, что независимо от того, что я пытаюсь, я всегда получаю исключение org.apache.commons.jxpath.JXPathNotFoundException.

SOAP ответ:

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <soap:Body>
      <VerifyEmailResponse xmlns="http://ws.cdyne.com/">
         <VerifyEmailResult>
            <ResponseText>Invalid Email Address</ResponseText>
            <ResponseCode>0</ResponseCode>
            <LastMailServer/>
            <GoodEmail>false</GoodEmail>
         </VerifyEmailResult>
      </VerifyEmailResponse>
   </soap:Body>
</soap:Envelope>

Java-код:

String payload = message.getPayloadAsString(); //The SOAP response
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db =  dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(payload));

Document doc = db.parse(is);
JXPathContext context = JXPathContext.newContext(doc);
String jxpathReply = (String) context.getValue("//soap:Envelope/soap:Body/VerifyEmailResponse/VerifyEmailResult/GoodEmail");

Мне кажется, что код ошибки предполагает, что это неправильный фильтр xpath. Я пробовал несколько разных, но не могу понять это правильно. Что я делаю неправильно?

1 ответ

Решение

Это самый часто задаваемый вопрос в XPath. Ищи "xpath default namespace" и вы найдете много хороших ответов.

Краткое объяснение состоит в том, что в XPath любое имя без префикса считается принадлежащим "без пространства имен". Поэтому, если мы хотим указать имена элементов, которые принадлежат некоторому пространству имен (включая пространство имен по умолчанию), эти имена должны иметь префикс, и указанный префикс должен быть связан (используя конкретный API движка XPath) с пространством имен uri пространства имен, в котором находится конкретный узел.

Следовательно, выражение может быть примерно таким:

/soap:Envelope/soap:Body/x:VerifyEmailResponse/x:VerifyEmailResult/x:GoodEmail

где префикс "x" ассоциируется ("регистрируя" эту ассоциацию пространства имен) с пространством имен "http://ws.cdyne.com/"

Другие вопросы по тегам