From: Stefan B. <bo...@ap...> - 2010-09-14 09:25:04
|
Hi, most if not all bug reports and user questions somehow boil down to finding the best strategy to make XMLUnit pick matching elements - and the 1.3 code isn't always obvious. I've changed trunk so that the whole strategy of selecting the best matching nodes among the children of test and control elements is pluggable: /** * Matches control and test nodes against each other, returns the * matching pairs. */ Iterable<Map.Entry<Node, Node>> match(Iterable<Node> controlNodes, Iterable<Node> testNodes); and IEnumerable<KeyValuePair<XmlNode, XmlNode>> Match(IEnumerable<XmlNode> controlNodes, IEnumerable<XmlNode> testNodes); I'm thinking of making the parent Node or its XPath (or both) available as well. The default strategy picks non-element nodes in order if they are of the same type (where CDATA and Text are the same type) and uses an ElementSelector (2.x term for ElementQualifier) for elements. The legacy layer can replace this with a strategy that adds the compareUnmatched logic. I'm also thinking of making ElementSelector allow some sort of middle ground where it can say "yes the nodes match" and "I know the nodes don't match" as well as "they don't really look like my business". For example if an ElementNameAndAttributeQualifier is asked to compare elements that don't have any attributes. This may allow us to pick a fallback strategy. It may even be possible to provide a builder with a conditional strategy, something like "for foo elements, check the bar attribute - for baz elements compare the nested text of xyzzy elements" which might look like NodeMatcher nm = NodeMatcherBuilder.setDefault(ElementSelectors.byName) .if(ElementName.is("foo")) .use(ElementSelectors.byNameAndAttributes("bar")) .if(ElementName.is("baz")) .use(ElementSelectors.byNameAndNestedTextRec(".//xyzzy")) .build(); Does that sound reasonable? Stefan |