/** * Walk the XML tree and validate all nodes. * * @param received * @param source * @param validationContext */ private void validateXmlTree( Node received, Node source, XmlMessageValidationContext validationContext, NamespaceContext namespaceContext, TestContext context) { switch (received.getNodeType()) { case Node.DOCUMENT_TYPE_NODE: doDocumentTypeDefinition(received, source, validationContext, namespaceContext, context); break; case Node.DOCUMENT_NODE: validateXmlTree( received.getFirstChild(), source.getFirstChild(), validationContext, namespaceContext, context); break; case Node.ELEMENT_NODE: doElement(received, source, validationContext, namespaceContext, context); break; case Node.TEXT_NODE: case Node.CDATA_SECTION_NODE: doText(received, source); break; case Node.ATTRIBUTE_NODE: throw new IllegalStateException(); case Node.COMMENT_NODE: doComment(received); break; case Node.PROCESSING_INSTRUCTION_NODE: doPI(received); break; } }
/** * Checks whether the given node contains a validation matcher * * @param node * @return true if node value contains validation matcher, false if not */ private boolean isValidationMatcherExpression(Node node) { switch (node.getNodeType()) { case Node.ELEMENT_NODE: return node.getFirstChild() != null && StringUtils.hasText(node.getFirstChild().getNodeValue()) && ValidationMatcherUtils.isValidationMatcherExpression( node.getFirstChild().getNodeValue().trim()); case Node.ATTRIBUTE_NODE: return StringUtils.hasText(node.getNodeValue()) && ValidationMatcherUtils.isValidationMatcherExpression(node.getNodeValue().trim()); default: return false; // validation matchers makes no sense } }
/** * Handle element node. * * @param received * @param source * @param validationContext */ private void doElement( Node received, Node source, XmlMessageValidationContext validationContext, NamespaceContext namespaceContext, TestContext context) { doElementNameValidation(received, source); doElementNamespaceValidation(received, source); // check if element is ignored either by xpath or by ignore placeholder in source message if (XmlValidationUtils.isElementIgnored( source, received, validationContext.getIgnoreExpressions(), namespaceContext)) { return; } // work on attributes if (log.isDebugEnabled()) { log.debug("Validating attributes for element: " + received.getLocalName()); } NamedNodeMap receivedAttr = received.getAttributes(); NamedNodeMap sourceAttr = source.getAttributes(); Assert.isTrue( countAttributes(receivedAttr) == countAttributes(sourceAttr), ValidationUtils.buildValueMismatchErrorMessage( "Number of attributes not equal for element '" + received.getLocalName() + "'", countAttributes(sourceAttr), countAttributes(receivedAttr))); for (int i = 0; i < receivedAttr.getLength(); i++) { doAttribute( received, receivedAttr.item(i), source, validationContext, namespaceContext, context); } // check if validation matcher on element is specified if (isValidationMatcherExpression(source)) { ValidationMatcherUtils.resolveValidationMatcher( source.getNodeName(), received.getFirstChild().getNodeValue().trim(), source.getFirstChild().getNodeValue().trim(), context); return; } // work on child nodes NodeList receivedChilds = received.getChildNodes(); NodeList sourceChilds = source.getChildNodes(); Assert.isTrue( receivedChilds.getLength() == sourceChilds.getLength(), ValidationUtils.buildValueMismatchErrorMessage( "Number of child elements not equal for element '" + received.getLocalName() + "'", sourceChilds.getLength(), receivedChilds.getLength())); for (int i = 0; i < receivedChilds.getLength(); i++) { this.validateXmlTree( receivedChilds.item(i), sourceChilds.item(i), validationContext, namespaceContext, context); } if (log.isDebugEnabled()) { log.debug( "Validation successful for element: " + received.getLocalName() + " (" + received.getNamespaceURI() + ")"); } }