You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ws.apache.org by ve...@apache.org on 2015/08/16 18:30:42 UTC

svn commit: r1696154 - in /webservices/axiom/trunk/testing: axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/ axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/ axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/ axiom...

Author: veithen
Date: Sun Aug 16 16:30:41 2015
New Revision: 1696154

URL: http://svn.apache.org/r1696154
Log:
Improve xml-truth:
- Establish equal treatment for data types supported natively and those added by extensions.
- Ensure that behavior is well defined if an object could be converted by two XMLFactory instances.

Modified:
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestGetDocumentElement.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestClone.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestGetSAXResult.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestRemoveChildren.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestAddAttributeMultiple.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestCloneOMElement2.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDetachWithDifferentBuilder.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDiscardPartiallyBuilt.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXSourceIdentityTransform.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestRemoveChildren.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/node/TestInsertSiblingAfterLastChild.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/omdom/element/TestCloneNodeIncomplete.java
    webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/body/TestCloneOMElement.java
    webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestCloneNode.java
    webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithIdentityStylesheet.java
    webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithStylesheet.java
    webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLTruth.java

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestGetDocumentElement.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestGetDocumentElement.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestGetDocumentElement.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/builder/TestGetDocumentElement.java Sun Aug 16 16:30:41 2015
@@ -72,7 +72,7 @@ public class TestGetDocumentElement exte
                 assertFalse(builder.isCompleted());
             }
             assertAbout(xml())
-                    .that(xml(newParent))
+                    .that(xml(OMElement.class, newParent))
                     .hasSameContentAs(xml("<newParent><root/></newParent>"));
             assertTrue(element.isComplete());
             // Since we discarded the document, the nodes in the epilog will not be accessible.

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestClone.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestClone.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestClone.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestClone.java Sun Aug 16 16:30:41 2015
@@ -38,7 +38,7 @@ public class TestClone extends Conforman
                 TEST_PARSER_CONFIGURATION, new InputSource(file.getUrl().toString())).getDocument();
         OMDocument clone = (OMDocument)original.clone(new OMCloneOptions());
         assertAbout(xml())
-                .that(xml(clone))
-                .hasSameContentAs(xml(original));
+                .that(xml(OMDocument.class, clone))
+                .hasSameContentAs(xml(OMDocument.class, original));
     }
 }

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestGetSAXResult.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestGetSAXResult.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestGetSAXResult.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestGetSAXResult.java Sun Aug 16 16:30:41 2015
@@ -48,7 +48,7 @@ public class TestGetSAXResult extends Co
         SAXResult result = document.getSAXResult();
         transformerFactory.newTransformer().transform(source, result);
         assertAbout(xml())
-                .that(xml(document))
+                .that(xml(OMDocument.class, document))
                 .ignoringWhitespaceInPrologAndEpilog()
                 .ignoringRedundantNamespaceDeclarations()
                 .expandingEntityReferences()

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestRemoveChildren.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestRemoveChildren.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestRemoveChildren.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/document/TestRemoveChildren.java Sun Aug 16 16:30:41 2015
@@ -81,7 +81,7 @@ public class TestRemoveChildren extends
         // new children.
         document.addChild(factory.createOMElement("newroot", null));
         assertAbout(xml())
-                .that(xml(document))
+                .that(xml(OMDocument.class, document))
                 .hasSameContentAs(xml("<newroot/>"));
     }
 }

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestAddAttributeMultiple.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestAddAttributeMultiple.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestAddAttributeMultiple.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestAddAttributeMultiple.java Sun Aug 16 16:30:41 2015
@@ -57,7 +57,7 @@ public class TestAddAttributeMultiple ex
         strategy.addAttribute(omElement, "attrNumber", attrNS2, "2");
     
         assertAbout(xml())
-                .that(xml(omElement))
+                .that(xml(OMElement.class, omElement))
                 .hasSameContentAs(xml(expectedXML));
     }
 }

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestCloneOMElement2.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestCloneOMElement2.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestCloneOMElement2.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestCloneOMElement2.java Sun Aug 16 16:30:41 2015
@@ -42,8 +42,8 @@ public class TestCloneOMElement2 extends
             OMElement original = OMXMLBuilderFactory.createOMBuilder(factory, TEST_PARSER_CONFIGURATION, in).getDocumentElement();
             OMElement clone = original.cloneOMElement();
             assertAbout(xml())
-                    .that(xml(clone))
-                    .hasSameContentAs(xml(original));
+                    .that(xml(OMElement.class, clone))
+                    .hasSameContentAs(xml(OMElement.class, original));
         } finally {
             in.close();
         }

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDetachWithDifferentBuilder.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDetachWithDifferentBuilder.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDetachWithDifferentBuilder.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDetachWithDifferentBuilder.java Sun Aug 16 16:30:41 2015
@@ -46,7 +46,7 @@ public class TestDetachWithDifferentBuil
         // builder.
         child.detach();
         ASSERT.that(child.isComplete()).isFalse();
-        ASSERT.about(xml()).that(xml(parent)).hasSameContentAs(xml(xml1));
-        ASSERT.about(xml()).that(xml(child)).hasSameContentAs(xml(xml2));
+        ASSERT.about(xml()).that(xml(OMElement.class, parent)).hasSameContentAs(xml(xml1));
+        ASSERT.about(xml()).that(xml(OMElement.class, child)).hasSameContentAs(xml(xml2));
     }
 }

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDiscardPartiallyBuilt.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDiscardPartiallyBuilt.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDiscardPartiallyBuilt.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestDiscardPartiallyBuilt.java Sun Aug 16 16:30:41 2015
@@ -54,7 +54,7 @@ public class TestDiscardPartiallyBuilt e
         
         element.discard();
         assertAbout(xml())
-                .that(xml(root))
+                .that(xml(OMElement.class, root))
                 .hasSameContentAs(xml("<root><sibling/></root>"));
         
         // Force the builder to complete the document. If the discard method didn't adjust the

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXSourceIdentityTransform.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXSourceIdentityTransform.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXSourceIdentityTransform.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestGetSAXSourceIdentityTransform.java Sun Aug 16 16:30:41 2015
@@ -58,7 +58,7 @@ public class TestGetSAXSourceIdentityTra
         transformer.transform(element.getSAXSource(cache), outputDocument.getSAXResult());
         
         assertAbout(xml())
-                .that(xml(outputDocument))
+                .that(xml(OMDocument.class, outputDocument))
                 .ignoringWhitespaceInPrologAndEpilog()
                 .hasSameContentAs(xml(getInput()));
         

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestRemoveChildren.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestRemoveChildren.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestRemoveChildren.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/element/TestRemoveChildren.java Sun Aug 16 16:30:41 2015
@@ -66,7 +66,7 @@ public class TestRemoveChildren extends
         // new children.
         element.addChild(factory.createOMElement("c", null));
         assertAbout(xml())
-                .that(xml(element))
+                .that(xml(OMElement.class, element))
                 .hasSameContentAs(xml("<root><c/></root>"));
     }
 }

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/node/TestInsertSiblingAfterLastChild.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/node/TestInsertSiblingAfterLastChild.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/node/TestInsertSiblingAfterLastChild.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/om/node/TestInsertSiblingAfterLastChild.java Sun Aug 16 16:30:41 2015
@@ -52,7 +52,7 @@ public class TestInsertSiblingAfterLastC
         // Now add c3 to parent using parent.addChild()
         parent.addChild(c3);
         assertAbout(xml())
-                .that(xml(parent))
+                .that(xml(OMElement.class, parent))
                 .ignoringRedundantNamespaceDeclarations()
                 .hasSameContentAs(xml("<ns:parent xmlns:ns=\"http://www.testuri.com\">" +
                         "<ns:c1 /><ns:c2 /><ns:c3 /></ns:parent>"));

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/omdom/element/TestCloneNodeIncomplete.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/omdom/element/TestCloneNodeIncomplete.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/omdom/element/TestCloneNodeIncomplete.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/omdom/element/TestCloneNodeIncomplete.java Sun Aug 16 16:30:41 2015
@@ -41,6 +41,6 @@ public class TestCloneNodeIncomplete ext
         Element element = (Element)OMXMLBuilderFactory.createOMBuilder(metaFactory.getOMFactory(),
                 new StringReader("<root><child1/><child2/></root>")).getDocumentElement();
         Element clone = (Element)element.cloneNode(true);
-        assertAbout(xml()).that(xml(clone)).hasSameContentAs(xml(element));
+        assertAbout(xml()).that(xml(Element.class, clone)).hasSameContentAs(xml(Element.class, element));
     }
 }

Modified: webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/body/TestCloneOMElement.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/body/TestCloneOMElement.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/body/TestCloneOMElement.java (original)
+++ webservices/axiom/trunk/testing/axiom-testsuite/src/main/java/org/apache/axiom/ts/soap/body/TestCloneOMElement.java Sun Aug 16 16:30:41 2015
@@ -46,16 +46,16 @@ public class TestCloneOMElement extends
         
         // first check whether both have the same information
         assertAbout(xml())
-                .that(xml(firstClonedBodyElement))
+                .that(xml(OMElement.class, firstClonedBodyElement))
                 .ignoringNamespaceDeclarations()
-                .hasSameContentAs(xml(body));
+                .hasSameContentAs(xml(OMElement.class, body));
         assertAbout(xml())
-                .that(xml(secondClonedBodyElement))
+                .that(xml(OMElement.class, secondClonedBodyElement))
                 .ignoringNamespaceDeclarations()
-                .hasSameContentAs(xml(body));
+                .hasSameContentAs(xml(OMElement.class, body));
         assertAbout(xml())
-                .that(xml(secondClonedBodyElement))
-                .hasSameContentAs(xml(firstClonedBodyElement));
+                .that(xml(OMElement.class, secondClonedBodyElement))
+                .hasSameContentAs(xml(OMElement.class, firstClonedBodyElement));
 
         // The clone is expected to be orphaned
         assertNull(firstClonedBodyElement.getParent());

Modified: webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestCloneNode.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestCloneNode.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestCloneNode.java (original)
+++ webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestCloneNode.java Sun Aug 16 16:30:41 2015
@@ -40,8 +40,8 @@ public class TestCloneNode extends DOMTe
         Document document = dbf.newDocumentBuilder().parse(file.getUrl().toString());
         Document document2 = (Document)document.cloneNode(true);
         assertAbout(xml())
-                .that(xml(document2))
+                .that(xml(Document.class, document2))
                 .treatingElementContentWhitespaceAsText()
-                .hasSameContentAs(xml(document));
+                .hasSameContentAs(xml(Document.class, document));
     }
 }

Modified: webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithIdentityStylesheet.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithIdentityStylesheet.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithIdentityStylesheet.java (original)
+++ webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithIdentityStylesheet.java Sun Aug 16 16:30:41 2015
@@ -55,8 +55,8 @@ public class TestTransformerWithIdentity
         Transformer transformer = xsltImplementation.newTransformerFactory().newTransformer(new DOMSource(stylesheet));
         transformer.transform(new DOMSource(document), new DOMResult(output));
         assertAbout(xml())
-                .that(xml(output))
+                .that(xml(Document.class, output))
                 .ignoringNamespaceDeclarations()
-                .hasSameContentAs(xml(document));
+                .hasSameContentAs(xml(Document.class, document));
     }
 }

Modified: webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithStylesheet.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithStylesheet.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithStylesheet.java (original)
+++ webservices/axiom/trunk/testing/dom-testsuite/src/main/java/org/apache/axiom/ts/dom/document/TestTransformerWithStylesheet.java Sun Aug 16 16:30:41 2015
@@ -45,8 +45,8 @@ public class TestTransformerWithStyleshe
         Transformer transformer = xsltImplementation.newTransformerFactory().newTransformer(new DOMSource(stylesheet));
         transformer.transform(new DOMSource(input), new DOMResult(actual));
         assertAbout(xml())
-                .that(xml(actual))
+                .that(xml(Document.class, actual))
                 .ignoringWhitespace()
-                .hasSameContentAs(xml(expected));
+                .hasSameContentAs(xml(Document.class, expected));
     }
 }

Modified: webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLTruth.java
URL: http://svn.apache.org/viewvc/webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLTruth.java?rev=1696154&r1=1696153&r2=1696154&view=diff
==============================================================================
--- webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLTruth.java (original)
+++ webservices/axiom/trunk/testing/xml-truth/src/main/java/org/apache/axiom/truth/xml/XMLTruth.java Sun Aug 16 16:30:41 2015
@@ -23,6 +23,8 @@ import java.io.InputStream;
 import java.io.Reader;
 import java.io.StringReader;
 import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.ServiceLoader;
 
 import javax.xml.stream.XMLInputFactory;
@@ -46,80 +48,162 @@ public final class XMLTruth {
         
     };
     
-    @SuppressWarnings("rawtypes")
-    private static final ServiceLoader<XMLFactory> factoryLoader = ServiceLoader.load(
-            XMLFactory.class, XMLTruth.class.getClassLoader());
+    private static final List<XMLFactory<?>> factories;
     
-    private XMLTruth() {}
+    static {
+        factories = new ArrayList<>();
+        factories.add(new XMLFactory<InputStream>() {
+            @Override
+            public Class<InputStream> getExpectedType() {
+                return InputStream.class;
+            }
 
-    public static SubjectFactory<XMLSubject,XML> xml() {
-        return SUBJECT_FACTORY;
-    }
+            @Override
+            public XML createXML(final InputStream in) {
+                return new StAXXML() {
+                    @Override
+                    XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException {
+                        return factory.createXMLStreamReader(in);
+                    }
+                };
+            }
+        });
+        factories.add(new XMLFactory<Reader>() {
+            @Override
+            public Class<Reader> getExpectedType() {
+                return Reader.class;
+            }
 
-    public static XML xml(Document document) {
-        return new DOMXML(document);
-    }
+            @Override
+            public XML createXML(final Reader reader) {
+                return new StAXXML() {
+                    @Override
+                    XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException {
+                        return factory.createXMLStreamReader(reader);
+                    }
+                };
+            }
+        });
+        factories.add(new XMLFactory<StreamSource>() {
+            @Override
+            public Class<StreamSource> getExpectedType() {
+                return StreamSource.class;
+            }
 
-    public static XML xml(Element element) {
-        return new DOMXML(element);
-    }
+            @Override
+            public XML createXML(final StreamSource source) {
+                return new StAXXML() {
+                    @Override
+                    XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException {
+                        return factory.createXMLStreamReader(source);
+                    }
+                };
+            }
+        });
+        factories.add(new XMLFactory<InputSource>() {
+            @Override
+            public Class<InputSource> getExpectedType() {
+                return InputSource.class;
+            }
 
-    public static XML xml(final InputSource is) {
-        final StreamSource source = new StreamSource();
-        source.setInputStream(is.getByteStream());
-        source.setReader(is.getCharacterStream());
-        source.setPublicId(is.getPublicId());
-        source.setSystemId(is.getSystemId());
-        return new StAXXML() {
             @Override
-            XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException {
-                return factory.createXMLStreamReader(source);
+            public XML createXML(InputSource is) {
+                StreamSource source = new StreamSource();
+                source.setInputStream(is.getByteStream());
+                source.setReader(is.getCharacterStream());
+                source.setPublicId(is.getPublicId());
+                source.setSystemId(is.getSystemId());
+                return xml(source);
             }
-        };
-    }
-    
-    public static XML xml(final InputStream in) {
-        return new StAXXML() {
+        });
+        factories.add(new XMLFactory<URL>() {
             @Override
-            XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException {
-                return factory.createXMLStreamReader(in);
+            public Class<URL> getExpectedType() {
+                return URL.class;
             }
-        };
-    }
 
-    public static XML xml(final Reader reader) {
-        return new StAXXML() {
             @Override
-            XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException {
-                return factory.createXMLStreamReader(reader);
+            public XML createXML(URL url) {
+                return xml(new StreamSource(url.toString()));
+            }
+        });
+        factories.add(new XMLFactory<String>() {
+            @Override
+            public Class<String> getExpectedType() {
+                return String.class;
             }
-        };
-    }
 
-    public static XML xml(final URL url) {
-        return new StAXXML() {
             @Override
-            XMLStreamReader createXMLStreamReader(XMLInputFactory factory) throws XMLStreamException {
-                return factory.createXMLStreamReader(new StreamSource(url.toString()));
+            public XML createXML(String xml) {
+                return xml(new StringReader(xml));
+            }
+        });
+        factories.add(new XMLFactory<byte[]>() {
+            @Override
+            public Class<byte[]> getExpectedType() {
+                return byte[].class;
+            }
+
+            @Override
+            public XML createXML(byte[] bytes) {
+                return xml(new ByteArrayInputStream(bytes));
+            }
+        });
+        factories.add(new XMLFactory<Document>() {
+            @Override
+            public Class<Document> getExpectedType() {
+                return Document.class;
             }
-        };
-    }
 
-    public static XML xml(String xml) {
-        return xml(new StringReader(xml));
+            @Override
+            public XML createXML(Document document) {
+                return new DOMXML(document);
+            }
+        });
+        factories.add(new XMLFactory<Element>() {
+            @Override
+            public Class<Element> getExpectedType() {
+                return Element.class;
+            }
+
+            @Override
+            public XML createXML(Element element) {
+                return new DOMXML(element);
+            }
+        });
+        for (XMLFactory<?> factory : ServiceLoader.load(
+                XMLFactory.class, XMLTruth.class.getClassLoader())) {
+            factories.add(factory);
+        }
     }
     
-    public static XML xml(byte[] bytes) {
-        return xml(new ByteArrayInputStream(bytes));
+    private XMLTruth() {}
+
+    public static SubjectFactory<XMLSubject,XML> xml() {
+        return SUBJECT_FACTORY;
     }
-    
-    public static XML xml(Object object) {
-        for (XMLFactory<?> factory : factoryLoader) {
-            if (factory.getExpectedType().isInstance(object)) {
-                return xml(factory, object);
+
+    public static <T> XML xml(Class<T> type, T object) {
+        XMLFactory<?> factory = null;
+        for (XMLFactory<?> candidate : factories) {
+            Class<?> expectedType = candidate.getExpectedType();
+            if ((type == null || expectedType.isAssignableFrom(type)) && expectedType.isInstance(object)) {
+                if (factory != null) {
+                    throw new IllegalArgumentException("Multiple matching XMLFactory instances found");
+                } else {
+                    factory = candidate;
+                }
             }
         }
-        throw new IllegalArgumentException();
+        if (factory == null) {
+            throw new IllegalArgumentException();
+        } else {
+            return xml(factory, object);
+        }
+    }
+    
+    public static XML xml(Object object) {
+        return xml((Class<Object>)null, object);
     }
     
     private static <T> XML xml(XMLFactory<T> factory, Object object) {