bug: handle xml with namespaces closes #1427 (#1445)

This commit is contained in:
Javier Alejandro Miño
2020-07-13 01:50:58 -05:00
committed by GitHub
parent adae31914e
commit d6cc0fcd65
2 changed files with 46 additions and 1 deletions

View File

@@ -16,7 +16,9 @@
package org.springframework.cloud.contract.verifier.util.xml
import com.sun.org.apache.xml.internal.security.utils.DOMNamespaceContext
import javax.xml.namespace.NamespaceContext
import java.util.stream.IntStream
import javax.xml.parsers.DocumentBuilder
@@ -87,10 +89,13 @@ class XmlToXPathsConverter {
private static String getNodeValue(String path, Object body) {
XPath xPath = XPathFactory.newInstance().newXPath()
DocumentBuilder documentBuilder = DocumentBuilderFactory.newInstance()
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance()
builderFactory.setNamespaceAware(true)
DocumentBuilder documentBuilder = builderFactory
.newDocumentBuilder()
Document parsedXml = documentBuilder.
parse(new InputSource(new StringReader(body as String)))
xPath.setNamespaceContext(new DOMNamespaceContext(parsedXml.documentElement))
return xPath.evaluate(path, parsedXml.documentElement)
}

View File

@@ -0,0 +1,40 @@
package org.springframework.cloud.contract.verifier.util.xml
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll
import javax.xml.xpath.XPathExpressionException
class XmlToXPathsConverterSpec extends Specification {
@Shared
String namedXml = '''<ns1:customer xmlns:ns1="http://demo.com/testns">
<email>customer@test.com</email>
</ns1:customer>
'''
@Shared
String unnamedXml = '''<customer>
<email>customer@test.com</email>
</customer>
'''
@Unroll
def "should generate [#expectedValue] for xPath [#value]"() {
expect:
value == expectedValue
where:
value || expectedValue
XmlToXPathsConverter.retrieveValueFromBody("/ns1:customer/email/text()", namedXml) || '''customer@test.com'''
XmlToXPathsConverter.retrieveValueFromBody("/customer/email/text()", namedXml) || ''''''
XmlToXPathsConverter.retrieveValueFromBody("/customer/email/text()", unnamedXml) || '''customer@test.com'''
}
@Unroll
def "should throw exception when searching for inexistent name space"() {
when:
XmlToXPathsConverter.retrieveValueFromBody("/ns1:customer/email/text()", unnamedXml)
then:
def e = thrown(XPathExpressionException)
e.message.contains('Prefix must resolve to a namespace: ns1')
}
}