Propchange: 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaElementValidator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaNamespaceContext.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaNamespaceContext.java?rev=1625632&view=auto
==============================================================================
--- 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaNamespaceContext.java
 (added)
+++ 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaNamespaceContext.java
 Wed Sep 17 15:32:44 2014
@@ -0,0 +1,268 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.commons.schema.docpath;
+
+import static org.junit.Assert.*;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.ws.commons.schema.constants.Constants;
+import org.apache.ws.commons.schema.docpath.XmlSchemaNamespaceContext;
+import org.junit.Test;
+
+public class TestXmlSchemaNamespaceContext {
+
+    @Test
+    public void test() {
+        XmlSchemaNamespaceContext nsContext = new XmlSchemaNamespaceContext();
+
+        assertEquals(2, nsContext.getDeclaredPrefixes().length);
+        assertArrayEquality(new String[] {Constants.XML_NS_PREFIX, 
Constants.XMLNS_ATTRIBUTE},
+                            nsContext.getDeclaredPrefixes());
+
+        Map<String, String> expPrefixToNsMap = new HashMap<String, String>();
+        expPrefixToNsMap.put(Constants.XML_NS_PREFIX, Constants.XML_NS_URI);
+        expPrefixToNsMap.put(Constants.XMLNS_ATTRIBUTE, 
Constants.XMLNS_ATTRIBUTE_NS_URI);
+
+        Map<String, String[]> expNsToPrefixMap = new HashMap<String, 
String[]>();
+
+        expNsToPrefixMap.put(Constants.XML_NS_URI, new String[] 
{Constants.XML_NS_PREFIX});
+
+        expNsToPrefixMap.put(Constants.XMLNS_ATTRIBUTE_NS_URI, new String[] 
{Constants.XMLNS_ATTRIBUTE});
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        // "avro" -> "http://avro.apache.org/AvroTest";
+        final String avroPrefix = "avro";
+        final String avroNs = "http://avro.apache.org/AvroTest";;
+
+        nsContext.addNamespace(avroPrefix, avroNs);
+        expPrefixToNsMap.put(avroPrefix, avroNs);
+        expNsToPrefixMap.put(avroNs, new String[] {avroPrefix});
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        // "dei" -> "http://xbrl.sec.gov/dei/2012-01-31";
+        final String deiPrefix = "dei";
+        final String deiNs = "http://xbrl.sec.gov/dei/2012-01-31";;
+
+        nsContext.addNamespace(deiPrefix, deiNs);
+        expPrefixToNsMap.put(deiPrefix, deiNs);
+        expNsToPrefixMap.put(deiNs, new String[] {deiPrefix});
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        // "iso4217" -> "http://www.xbrl.org/2003/iso4217";
+        final String iso4217Prefix = "iso4217";
+        final String iso4217Ns = "http://www.xbrl.org/2003/iso4217";;
+
+        nsContext.addNamespace(iso4217Prefix, iso4217Ns);
+        expPrefixToNsMap.put(iso4217Prefix, iso4217Ns);
+        expNsToPrefixMap.put(iso4217Ns, new String[] {iso4217Prefix});
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        // Attach "dei" to "http://www.xbrl.org/2003/iso4217";
+        nsContext.addNamespace(deiPrefix, iso4217Ns);
+        expPrefixToNsMap.put(deiPrefix, iso4217Ns);
+        expNsToPrefixMap.put(iso4217Ns, new String[] {iso4217Prefix, 
deiPrefix});
+        expNsToPrefixMap.remove(deiNs);
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        // Attach "iso4217" to "http://xbrl.sec.gov/dei/2012-01-31";
+        nsContext.addNamespace(iso4217Prefix, deiNs);
+        expPrefixToNsMap.put(iso4217Prefix, deiNs);
+        expNsToPrefixMap.put(deiNs, new String[] {iso4217Prefix});
+        expNsToPrefixMap.put(iso4217Ns, new String[] {deiPrefix});
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        // Remove "dei" to "http://www.xbrl.org/2003/iso4217"; mapping.
+        nsContext.removeNamespace(deiPrefix);
+        expPrefixToNsMap.put(deiPrefix, deiNs);
+        expNsToPrefixMap.put(deiNs, new String[] {iso4217Prefix, deiPrefix});
+        expNsToPrefixMap.remove(iso4217Ns);
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        // Remove "iso4217" to "http://xbrl.sec.gov/dei/2012-01-31"; mapping.
+        nsContext.removeNamespace(iso4217Prefix);
+        expPrefixToNsMap.put(iso4217Prefix, iso4217Ns);
+        expNsToPrefixMap.put(deiNs, new String[] {deiPrefix});
+        expNsToPrefixMap.put(iso4217Ns, new String[] {iso4217Prefix});
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        // Remove "iso4217" to "http://www.xbrl.org/2003/iso4217"; mapping.
+        nsContext.removeNamespace(iso4217Prefix);
+        expPrefixToNsMap.remove(iso4217Prefix);
+        expNsToPrefixMap.remove(iso4217Ns);
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        // Remove "dei" to "http:///xbrl.sec.gov/dei/2012-01-31";
+        nsContext.removeNamespace(deiPrefix);
+        expPrefixToNsMap.remove(deiPrefix);
+        expNsToPrefixMap.remove(deiNs);
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        // Try to remove a dead prefix.
+        try {
+            nsContext.removeNamespace(deiPrefix);
+            fail("Should not have been able to remove " + deiPrefix);
+        } catch (IllegalStateException ise) {
+            // Passes.
+        }
+
+        // Add the dei namespace back in under the avro namespace.
+        nsContext.addNamespace(deiPrefix, avroNs);
+        expPrefixToNsMap.put(deiPrefix, avroNs);
+        expNsToPrefixMap.put(avroNs, new String[] {deiPrefix, avroPrefix});
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        // Remove the "avro" to "http://avro.apache.org/AvroTest"; mapping.
+        nsContext.removeNamespace(avroPrefix);
+        expPrefixToNsMap.remove(avroPrefix);
+        expNsToPrefixMap.put(avroNs, new String[] {deiPrefix});
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+
+        nsContext.removeNamespace(deiPrefix);
+        expPrefixToNsMap.remove(deiPrefix);
+        expNsToPrefixMap.remove(avroNs);
+
+        assertEquality(expPrefixToNsMap, expNsToPrefixMap, nsContext);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNullPrefixForNamespace() {
+        XmlSchemaNamespaceContext nsContext = new XmlSchemaNamespaceContext();
+        nsContext.getNamespaceURI(null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testNullNamespaceForPrefix() {
+        XmlSchemaNamespaceContext nsContext = new XmlSchemaNamespaceContext();
+        nsContext.getPrefix(null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testAddNullNamespaceAndPrefix() {
+        XmlSchemaNamespaceContext nsContext = new XmlSchemaNamespaceContext();
+        nsContext.addNamespace(null, null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testAddNullNamespaceWithPrefix() {
+        XmlSchemaNamespaceContext nsContext = new XmlSchemaNamespaceContext();
+        nsContext.addNamespace("avro", null);
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testAddEmptyNamespaceWithPrefix() {
+        XmlSchemaNamespaceContext nsContext = new XmlSchemaNamespaceContext();
+        nsContext.addNamespace("avro", "");
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testGetPrefixesWithNullNamespace() {
+        XmlSchemaNamespaceContext nsContext = new XmlSchemaNamespaceContext();
+        nsContext.getPrefixes(null);
+    }
+
+    @Test
+    public void testNamespaceNotFound() {
+        XmlSchemaNamespaceContext nsContext = new XmlSchemaNamespaceContext();
+        assertNull(nsContext.getPrefix("urn:avro:test"));
+        assertEquals(Constants.NULL_NS_URI, nsContext.getNamespaceURI("avro"));
+    }
+
+    static void assertEquality(Map<String, String> expPrefixToNamespace, 
Map<String, String[]> expNsToPrefix,
+                               XmlSchemaNamespaceContext actual) {
+
+        final Set<String> pfxKeys = expPrefixToNamespace.keySet();
+        final String[] prefixes = pfxKeys.toArray(new String[pfxKeys.size()]);
+
+        assertArrayEquality(prefixes, actual.getDeclaredPrefixes());
+
+        for (String prefix : prefixes) {
+            final String expNamespace = expPrefixToNamespace.get(prefix);
+
+            assertEquals(expNamespace, actual.getNamespaceURI(prefix));
+        }
+
+        for (String expNamespace : expNsToPrefix.keySet()) {
+            final String[] expPrefixes = expNsToPrefix.get(expNamespace);
+
+            assertArrayEquality(expPrefixes, actual.getPrefixes(expNamespace));
+
+            final String firstPrefix = actual.getPrefix(expNamespace);
+            boolean found = false;
+            for (int pfxIdx = 0; pfxIdx < expPrefixes.length; ++pfxIdx) {
+                if (expPrefixes[pfxIdx].equals(firstPrefix)) {
+                    found = true;
+                    break;
+                }
+            }
+
+            assertTrue("Could not find \"" + firstPrefix + "\" in the expected 
prefix list.", found);
+
+        }
+    }
+
+    static void assertArrayEquality(String[] expected, String[] actual) {
+        assertEquals(expected.length, actual.length);
+
+        int found = 0;
+        for (int expIndex = 0; expIndex < expected.length; ++expIndex) {
+            for (int actIndex = 0; actIndex < actual.length; ++actIndex) {
+                if (expected[expIndex].equals(actual[actIndex])) {
+                    ++found;
+                    break;
+                }
+            }
+        }
+        assertEquals(expected.length, found);
+    }
+
+    static void assertArrayEquality(String[] expected, Iterator actual) {
+        HashSet<String> expSet = new HashSet<String>();
+        for (String exp : expected) {
+            expSet.add(exp);
+        }
+
+        while (actual.hasNext()) {
+            final String next = actual.next().toString();
+            assertTrue("Could not find " + next + " in the expected set.", 
expSet.contains(next));
+            expSet.remove(next);
+        }
+
+        if (!expSet.isEmpty()) {
+            fail("The expected list has more elements than the actual.");
+        }
+    }
+}

Propchange: 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaNamespaceContext.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaPathFinder.java
URL: 
http://svn.apache.org/viewvc/webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaPathFinder.java?rev=1625632&view=auto
==============================================================================
--- 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaPathFinder.java
 (added)
+++ 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaPathFinder.java
 Wed Sep 17 15:32:44 2014
@@ -0,0 +1,1316 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.commons.schema.docpath;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.FileReader;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.testutils.UtilsForTests;
+import org.apache.ws.commons.schema.walker.XmlSchemaBaseSimpleType;
+import org.apache.ws.commons.schema.walker.XmlSchemaWalker;
+import org.apache.ws.commons.schema.walker.XmlSchemaTypeInfo;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.w3c.dom.Document;
+
+public class TestXmlSchemaPathFinder {
+
+    private static final String TESTSCHEMA_NS = 
"http://avro.apache.org/AvroTest";;
+    private static final String COMPLEX_SCHEMA_NS = "urn:avro:complex_schema";
+
+    private static DocumentBuilderFactory dbf;
+
+    private DocumentBuilder docBuilder;
+
+    @BeforeClass
+    public static void setUpBeforeClass() throws Exception {
+        dbf = DocumentBuilderFactory.newInstance();
+        dbf.setNamespaceAware(true);
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        docBuilder = dbf.newDocumentBuilder();
+    }
+
+    @Test
+    public void testRoot() throws Exception {
+        final QName root = new QName("http://avro.apache.org/AvroTest";, 
"root");
+
+        final File schemaFile = UtilsForTests.buildFile("src", "test", 
"resources", "test_schema.xsd");
+
+        final File xmlFile = UtilsForTests.buildFile("src", "test", 
"resources", "test1_root.xml");
+
+        XmlSchemaPathNode traversal = runTest(schemaFile, xmlFile, root);
+
+        Map<QName, ExpectedElement> expectedElements = new HashMap<QName, 
ExpectedElement>();
+
+        expectedElements.put(root, new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        ExpectedNode node = new ExpectedNode(
+                                             
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                             1,
+                                             1,
+                                             Collections
+                                                 .<SortedMap<Integer, 
ExpectedNode>> singletonList(new TreeMap<Integer, ExpectedNode>()));
+
+        node.setElemQName(new QName(TESTSCHEMA_NS, "root"));
+
+        ExpectedNode.validate(root.toString(), node, 
traversal.getDocumentNode(), expectedElements);
+
+        ArrayList<ExpectedPathNode> expPath = new 
ArrayList<ExpectedPathNode>();
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
node, 1));
+
+        validate(expPath, traversal);
+    }
+
+    @Test
+    public void testChildren() throws Exception {
+        final QName root = new QName("http://avro.apache.org/AvroTest";, 
"root");
+
+        final File schemaFile = UtilsForTests.buildFile("src", "test", 
"resources", "test_schema.xsd");
+
+        final File xmlFile = UtilsForTests.buildFile("src", "test", 
"resources", "test2_children.xml");
+
+        XmlSchemaPathNode traversal = runTest(schemaFile, xmlFile, root);
+
+        Map<QName, ExpectedElement> expectedElements = new HashMap<QName, 
ExpectedElement>();
+
+        expectedElements.put(root, new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        expectedElements.put(new QName(TESTSCHEMA_NS, "primitive"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.STRING)));
+
+        expectedElements.put(new QName(TESTSCHEMA_NS, "nonNullPrimitive"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.STRING)));
+
+        ExpectedNode primitive = new ExpectedNode(
+                                                  
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                  1,
+                                                  1,
+                                                  Collections
+                                                      .<SortedMap<Integer, 
ExpectedNode>> singletonList(new TreeMap<Integer, ExpectedNode>()));
+        primitive.setElemQName(new QName(TESTSCHEMA_NS, "primitive"));
+
+        ExpectedNode nonNullPrimitive = new ExpectedNode(
+                                                         
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                         1,
+                                                         1,
+                                                         Collections
+                                                             
.<SortedMap<Integer, ExpectedNode>> singletonList(new TreeMap<Integer, 
ExpectedNode>()));
+        nonNullPrimitive.setElemQName(new QName(TESTSCHEMA_NS, 
"nonNullPrimitive"));
+
+        // avro:primitive is the first choice; its index is 0
+        TreeMap<Integer, ExpectedNode> choicePrimitiveChild = new 
TreeMap<Integer, ExpectedNode>();
+        choicePrimitiveChild.put(0, primitive);
+
+        // avro:nonNullPrimitive is the second choice; its index is 1
+        TreeMap<Integer, ExpectedNode> choiceNonNullPrimitiveChild = new 
TreeMap<Integer, ExpectedNode>();
+        choiceNonNullPrimitiveChild.put(1, nonNullPrimitive);
+
+        ArrayList<SortedMap<Integer, ExpectedNode>> choiceChildren = new 
ArrayList<SortedMap<Integer, ExpectedNode>>();
+
+        for (int i = 0; i < 9; ++i) {
+            choiceChildren.add(choicePrimitiveChild);
+        }
+        for (int i = 0; i < 8; ++i) {
+            choiceChildren.add(choiceNonNullPrimitiveChild);
+        }
+
+        ExpectedNode choiceNode = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.CHOICE, 0L, Long.MAX_VALUE,
+                                                   choiceChildren);
+
+        TreeMap<Integer, ExpectedNode> sequenceChild = new TreeMap<Integer, 
ExpectedNode>();
+        sequenceChild.put(0, choiceNode);
+
+        ExpectedNode sequenceNode = new ExpectedNode(
+                                                     
XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                     1,
+                                                     1,
+                                                     Collections
+                                                         .<SortedMap<Integer, 
ExpectedNode>> singletonList(sequenceChild));
+
+        TreeMap<Integer, ExpectedNode> rootChild = new TreeMap<Integer, 
ExpectedNode>();
+        rootChild.put(0, sequenceNode);
+
+        ExpectedNode rootNode = new ExpectedNode(
+                                                 
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                 1,
+                                                 1,
+                                                 Collections
+                                                     .<SortedMap<Integer, 
ExpectedNode>> singletonList(rootChild));
+        rootNode.setElemQName(new QName(TESTSCHEMA_NS, "root"));
+
+        ExpectedNode.validate(root.toString(), rootNode, 
traversal.getDocumentNode(), expectedElements);
+
+        ArrayList<ExpectedPathNode> expPath = new 
ArrayList<ExpectedPathNode>();
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
rootNode, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
sequenceNode, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
choiceNode, 1));
+
+        int choiceIter = 1;
+
+        for (int primIter = 0; primIter < 9; ++primIter) {
+            expPath.add(new 
ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, primitive, 1));
+
+            expPath.add(new 
ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, primitive, 1));
+
+            expPath.add(new 
ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, choiceNode, choiceIter));
+
+            expPath.add(new 
ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, choiceNode, 
++choiceIter));
+        }
+
+        for (int nonNullPrimIter = 0; nonNullPrimIter < 7; ++nonNullPrimIter) {
+            expPath.add(new 
ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, nonNullPrimitive, 1));
+
+            expPath.add(new 
ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, nonNullPrimitive, 1));
+
+            expPath.add(new 
ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, choiceNode, choiceIter));
+
+            expPath.add(new 
ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, choiceNode, 
++choiceIter));
+        }
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
choiceNode, choiceIter));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
sequenceNode, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
rootNode, 1));
+
+        validate(expPath, traversal);
+    }
+
+    @Test
+    public void testGrandchildren() throws Exception {
+        final QName root = new QName("http://avro.apache.org/AvroTest";, 
"root");
+
+        final File schemaFile = UtilsForTests.buildFile("src", "test", 
"resources", "test_schema.xsd");
+
+        final File xmlFile = UtilsForTests.buildFile("src", "test", 
"resources", "test3_grandchildren.xml");
+
+        XmlSchemaPathNode traversal = runTest(schemaFile, xmlFile, root);
+
+        Map<QName, ExpectedElement> expectedElements = new HashMap<QName, 
ExpectedElement>();
+
+        expectedElements.put(root, new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        expectedElements.put(new QName(TESTSCHEMA_NS, "primitive"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.STRING)));
+
+        expectedElements.put(new QName(TESTSCHEMA_NS, "nonNullPrimitive"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.STRING)));
+
+        expectedElements.put(new QName(TESTSCHEMA_NS, "map"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        expectedElements.put(new QName(TESTSCHEMA_NS, "record"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        ExpectedNode primitive = new ExpectedNode(
+                                                  
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                  1,
+                                                  1,
+                                                  Collections
+                                                      .<SortedMap<Integer, 
ExpectedNode>> singletonList(new TreeMap<Integer, ExpectedNode>()));
+        primitive.setElemQName(new QName(TESTSCHEMA_NS, "primitive"));
+
+        ExpectedNode nonNullPrimitive = new ExpectedNode(
+                                                         
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                         1,
+                                                         1,
+                                                         Collections
+                                                             
.<SortedMap<Integer, ExpectedNode>> singletonList(new TreeMap<Integer, 
ExpectedNode>()));
+        nonNullPrimitive.setElemQName(new QName(TESTSCHEMA_NS, 
"nonNullPrimitive"));
+
+        // avro:primitive is the first choice; its index is 0
+        TreeMap<Integer, ExpectedNode> choicePrimitiveChild = new 
TreeMap<Integer, ExpectedNode>();
+        choicePrimitiveChild.put(0, primitive);
+
+        // avro:nonNullPrimitive is the second choice; its index is 1
+        TreeMap<Integer, ExpectedNode> choiceNonNullPrimitiveChild = new 
TreeMap<Integer, ExpectedNode>();
+        choiceNonNullPrimitiveChild.put(1, nonNullPrimitive);
+
+        // map 1
+        ArrayList<SortedMap<Integer, ExpectedNode>> map1ChoiceChildren = new 
ArrayList<SortedMap<Integer, ExpectedNode>>();
+        map1ChoiceChildren.add(choicePrimitiveChild);
+        map1ChoiceChildren.add(choiceNonNullPrimitiveChild);
+
+        ExpectedNode map1Choice = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.CHOICE, 0, Long.MAX_VALUE,
+                                                   map1ChoiceChildren);
+
+        SortedMap<Integer, ExpectedNode> map1SeqChildren = new 
TreeMap<Integer, ExpectedNode>();
+        map1SeqChildren.put(0, map1Choice);
+
+        ExpectedNode map1Seq = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                
Collections.singletonList(map1SeqChildren));
+
+        SortedMap<Integer, ExpectedNode> map1Children = new TreeMap<Integer, 
ExpectedNode>();
+        map1Children.put(0, map1Seq);
+
+        ExpectedNode map1 = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                             
Collections.singletonList(map1Children));
+        map1.setElemQName(new QName(TESTSCHEMA_NS, "map"));
+
+        // avro:map is a substitution of avro:record, its index is 2
+        SortedMap<Integer, ExpectedNode> map1SubsGrpChild = new 
TreeMap<Integer, ExpectedNode>();
+        map1SubsGrpChild.put(1, map1);
+
+        ExpectedNode map1SubstGroup = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SUBSTITUTION_GROUP, 1,
+                                                       1, 
Collections.singletonList(map1SubsGrpChild));
+
+        SortedMap<Integer, ExpectedNode> choiceMap1Child = new 
TreeMap<Integer, ExpectedNode>();
+        choiceMap1Child.put(2, map1SubstGroup);
+
+        // map 2
+        SortedMap<Integer, ExpectedNode> map2ChoiceChildren = new 
TreeMap<Integer, ExpectedNode>();
+        map2ChoiceChildren.put(0, primitive);
+
+        ExpectedNode map2Choice = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.CHOICE, 0, Long.MAX_VALUE,
+                                                   
Collections.singletonList(map2ChoiceChildren));
+
+        SortedMap<Integer, ExpectedNode> map2SequenceChildren = new 
TreeMap<Integer, ExpectedNode>();
+        map2SequenceChildren.put(0, map2Choice);
+
+        ExpectedNode map2Seq = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                
Collections.singletonList(map2SequenceChildren));
+
+        SortedMap<Integer, ExpectedNode> map2Children = new TreeMap<Integer, 
ExpectedNode>();
+        map2Children.put(0, map2Seq);
+
+        ExpectedNode map2 = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                             
Collections.singletonList(map2Children));
+        map2.setElemQName(new QName(TESTSCHEMA_NS, "map"));
+
+        SortedMap<Integer, ExpectedNode> map2SubstGrpChild = new 
TreeMap<Integer, ExpectedNode>();
+        map2SubstGrpChild.put(1, map2);
+
+        ExpectedNode map2SubstGrp = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SUBSTITUTION_GROUP, 1, 1,
+                                                     
Collections.singletonList(map2SubstGrpChild));
+
+        SortedMap<Integer, ExpectedNode> choiceMap2Child = new 
TreeMap<Integer, ExpectedNode>();
+        choiceMap2Child.put(2, map2SubstGrp);
+
+        // map 4, which is owned by map 3
+        SortedMap<Integer, ExpectedNode> map4ChoiceChildren = new 
TreeMap<Integer, ExpectedNode>();
+        map4ChoiceChildren.put(1, nonNullPrimitive);
+
+        ExpectedNode map4Choice = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.CHOICE, 0, Long.MAX_VALUE,
+                                                   
Collections.singletonList(map4ChoiceChildren));
+
+        SortedMap<Integer, ExpectedNode> map4SeqChildren = new 
TreeMap<Integer, ExpectedNode>();
+        map4SeqChildren.put(0, map4Choice);
+
+        ExpectedNode map4Seq = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                
Collections.singletonList(map4SeqChildren));
+
+        SortedMap<Integer, ExpectedNode> map4Children = new TreeMap<Integer, 
ExpectedNode>();
+        map4Children.put(0, map4Seq);
+
+        ExpectedNode map4 = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                             
Collections.singletonList(map4Children));
+        map4.setElemQName(new QName(TESTSCHEMA_NS, "map"));
+
+        SortedMap<Integer, ExpectedNode> map4SubstGrpChildren = new 
TreeMap<Integer, ExpectedNode>();
+        map4SubstGrpChildren.put(1, map4);
+
+        ExpectedNode map4SubstGrp = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SUBSTITUTION_GROUP, 1, 1,
+                                                     
Collections.singletonList(map4SubstGrpChildren));
+
+        // map 5, which is owned by map 3
+        SortedMap<Integer, ExpectedNode> map5ChoiceChildren = new 
TreeMap<Integer, ExpectedNode>();
+        map5ChoiceChildren.put(0, primitive);
+
+        ExpectedNode map5Choice = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.CHOICE, 0, Long.MAX_VALUE,
+                                                   
Collections.singletonList(map5ChoiceChildren));
+
+        SortedMap<Integer, ExpectedNode> map5SeqChildren = new 
TreeMap<Integer, ExpectedNode>();
+        map5SeqChildren.put(0, map5Choice);
+
+        ExpectedNode map5Seq = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                
Collections.singletonList(map5SeqChildren));
+
+        SortedMap<Integer, ExpectedNode> map5Children = new TreeMap<Integer, 
ExpectedNode>();
+        map5Children.put(0, map5Seq);
+
+        ExpectedNode map5 = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                             
Collections.singletonList(map5Children));
+        map5.setElemQName(new QName(TESTSCHEMA_NS, "map"));
+
+        SortedMap<Integer, ExpectedNode> map5SubstGrpChildren = new 
TreeMap<Integer, ExpectedNode>();
+        map5SubstGrpChildren.put(1, map5);
+
+        ExpectedNode map5SubstGrp = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SUBSTITUTION_GROUP, 1, 1,
+                                                     
Collections.singletonList(map5SubstGrpChildren));
+
+        // map 3
+        ArrayList<SortedMap<Integer, ExpectedNode>> map3ChoiceChildren = new 
ArrayList<SortedMap<Integer, ExpectedNode>>();
+
+        SortedMap<Integer, ExpectedNode> map3Child1 = new TreeMap<Integer, 
ExpectedNode>();
+        map3Child1.put(0, primitive);
+
+        SortedMap<Integer, ExpectedNode> map3Child2 = new TreeMap<Integer, 
ExpectedNode>();
+        map3Child2.put(2, map4SubstGrp);
+
+        SortedMap<Integer, ExpectedNode> map3Child3 = new TreeMap<Integer, 
ExpectedNode>();
+        map3Child3.put(2, map5SubstGrp);
+
+        map3ChoiceChildren.add(map3Child1);
+        map3ChoiceChildren.add(map3Child2);
+        map3ChoiceChildren.add(map3Child3);
+
+        ExpectedNode map3Choice = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.CHOICE, 0, Long.MAX_VALUE,
+                                                   map3ChoiceChildren);
+
+        SortedMap<Integer, ExpectedNode> map3SeqChildren = new 
TreeMap<Integer, ExpectedNode>();
+        map3SeqChildren.put(0, map3Choice);
+
+        ExpectedNode map3Seq = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                
Collections.singletonList(map3SeqChildren));
+
+        SortedMap<Integer, ExpectedNode> map3Children = new TreeMap<Integer, 
ExpectedNode>();
+        map3Children.put(0, map3Seq);
+
+        ExpectedNode map3 = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                             
Collections.singletonList(map3Children));
+        map3.setElemQName(new QName(TESTSCHEMA_NS, "map"));
+
+        SortedMap<Integer, ExpectedNode> map3SubstGrpChildren = new 
TreeMap<Integer, ExpectedNode>();
+        map3SubstGrpChildren.put(1, map3);
+
+        ExpectedNode map3SubstGrp = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SUBSTITUTION_GROUP, 1, 1,
+                                                     
Collections.singletonList(map3SubstGrpChildren));
+
+        SortedMap<Integer, ExpectedNode> choiceMap3Child = new 
TreeMap<Integer, ExpectedNode>();
+        choiceMap3Child.put(2, map3SubstGrp);
+
+        // avro:record
+        SortedMap<Integer, ExpectedNode> recordChoiceChildren = new 
TreeMap<Integer, ExpectedNode>();
+        recordChoiceChildren.put(1, nonNullPrimitive);
+
+        ExpectedNode recordChoice = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.CHOICE, 0,
+                                                     Long.MAX_VALUE,
+                                                     
Collections.singletonList(recordChoiceChildren));
+
+        SortedMap<Integer, ExpectedNode> recordSeqChildren = new 
TreeMap<Integer, ExpectedNode>();
+        recordSeqChildren.put(0, recordChoice);
+
+        ExpectedNode recordSeq = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                  
Collections.singletonList(recordSeqChildren));
+
+        SortedMap<Integer, ExpectedNode> recordChildren = new TreeMap<Integer, 
ExpectedNode>();
+        recordChildren.put(0, recordSeq);
+
+        ExpectedNode record = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                               
Collections.singletonList(recordChildren));
+        record.setElemQName(new QName(TESTSCHEMA_NS, "record"));
+
+        SortedMap<Integer, ExpectedNode> recordSubstGrpChildren = new 
TreeMap<Integer, ExpectedNode>();
+        recordSubstGrpChildren.put(0, record);
+
+        ExpectedNode recordSubstGrp = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SUBSTITUTION_GROUP, 1,
+                                                       1, 
Collections.singletonList(recordSubstGrpChildren));
+
+        SortedMap<Integer, ExpectedNode> choiceRecordChild = new 
TreeMap<Integer, ExpectedNode>();
+        choiceRecordChild.put(2, recordSubstGrp);
+
+        // root
+        ArrayList<SortedMap<Integer, ExpectedNode>> choiceChildren = new 
ArrayList<SortedMap<Integer, ExpectedNode>>();
+
+        choiceChildren.add(choicePrimitiveChild);
+        choiceChildren.add(choiceNonNullPrimitiveChild);
+        choiceChildren.add(choiceMap1Child);
+        choiceChildren.add(choiceMap2Child);
+        choiceChildren.add(choiceRecordChild);
+        choiceChildren.add(choiceMap3Child);
+        choiceChildren.add(choiceNonNullPrimitiveChild);
+        choiceChildren.add(choiceNonNullPrimitiveChild);
+
+        ExpectedNode choiceNode = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.CHOICE, 0L, Long.MAX_VALUE,
+                                                   choiceChildren);
+
+        TreeMap<Integer, ExpectedNode> sequenceChild = new TreeMap<Integer, 
ExpectedNode>();
+        sequenceChild.put(0, choiceNode);
+
+        ExpectedNode sequenceNode = new ExpectedNode(
+                                                     
XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                     1,
+                                                     1,
+                                                     Collections
+                                                         .<SortedMap<Integer, 
ExpectedNode>> singletonList(sequenceChild));
+
+        TreeMap<Integer, ExpectedNode> rootChild = new TreeMap<Integer, 
ExpectedNode>();
+        rootChild.put(0, sequenceNode);
+
+        ExpectedNode rootNode = new ExpectedNode(
+                                                 
XmlSchemaStateMachineNode.Type.ELEMENT,
+                                                 1,
+                                                 1,
+                                                 Collections
+                                                     .<SortedMap<Integer, 
ExpectedNode>> singletonList(rootChild));
+        rootNode.setElemQName(new QName(TESTSCHEMA_NS, "root"));
+
+        ExpectedNode.validate(root.toString(), rootNode, 
traversal.getDocumentNode(), expectedElements);
+
+        ArrayList<ExpectedPathNode> expPath = new 
ArrayList<ExpectedPathNode>();
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
rootNode, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
sequenceNode, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
choiceNode, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
primitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
primitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
choiceNode, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
choiceNode, 2));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
choiceNode, 2));
+
+        // Path Index 10
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
choiceNode, 3));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map1SubstGroup, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map1, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map1Seq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map1Choice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
primitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
primitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map1Choice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
map1Choice, 2));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
nonNullPrimitive, 1));
+
+        // Path Index 20
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map1Choice, 2));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map1Seq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map1, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map1SubstGroup, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
choiceNode, 3));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
choiceNode, 4));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map2SubstGrp, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map2, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map2Seq, 1));
+
+        // Path Index 30
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map2Choice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
primitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
primitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map2Choice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map2Seq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map2, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map2SubstGrp, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
choiceNode, 4));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
choiceNode, 5));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
recordSubstGrp, 1));
+
+        // Path Index 40
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
record, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
recordSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
recordChoice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
recordChoice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
recordSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
record, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
recordSubstGrp, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
choiceNode, 5));
+
+        // Path Index 50
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
choiceNode, 6));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map3SubstGrp, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map3, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map3Seq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map3Choice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
primitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
primitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map3Choice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
map3Choice, 2));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map4SubstGrp, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map4, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map4Seq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map4Choice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map4Choice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map4Seq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map4, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map4SubstGrp, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map3Choice, 2));
+
+        // Path Index 70
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
map3Choice, 3));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map5SubstGrp, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map5, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map5Seq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
map5Choice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
primitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
primitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map5Choice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map5Seq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map5, 1));
+
+        // Path Index 80
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map5SubstGrp, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map3Choice, 3));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map3Seq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map3, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
map3SubstGrp, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
choiceNode, 6));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
choiceNode, 7));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
choiceNode, 7));
+
+        // Path Index 90
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
choiceNode, 8));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
nonNullPrimitive, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
choiceNode, 8));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
sequenceNode, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
rootNode, 1));
+
+        validate(expPath, traversal);
+    }
+
+    @Test
+    public void testComplex() throws Exception {
+        final QName root = new QName("urn:avro:complex_schema", "root");
+
+        final File complexSchemaFile = UtilsForTests.buildFile("src", "test", 
"resources",
+                                                               
"complex_schema.xsd");
+
+        final File testSchemaFile = UtilsForTests.buildFile("src", "test", 
"resources", "test_schema.xsd");
+
+        final File xmlFile = UtilsForTests.buildFile("src", "test", 
"resources", "complex_test1.xml");
+
+        XmlSchemaCollection xmlSchemaCollection = new XmlSchemaCollection();
+
+        FileReader schemaFileReader = null;
+        try {
+            schemaFileReader = new FileReader(complexSchemaFile);
+            xmlSchemaCollection.read(new StreamSource(schemaFileReader));
+        } finally {
+            if (schemaFileReader != null) {
+                schemaFileReader.close();
+            }
+        }
+
+        schemaFileReader = null;
+        try {
+            schemaFileReader = new FileReader(testSchemaFile);
+            xmlSchemaCollection.read(new StreamSource(schemaFileReader));
+        } finally {
+            if (schemaFileReader != null) {
+                schemaFileReader.close();
+            }
+        }
+
+        XmlSchemaPathNode traversal = runTest(xmlSchemaCollection, xmlFile, 
root);
+
+        Map<QName, ExpectedElement> expectedElements = new HashMap<QName, 
ExpectedElement>();
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "realRoot"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "backtrack"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "allTheThings"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "prohibit"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "anyAndFriends"),
+                             new ExpectedElement(new XmlSchemaTypeInfo(true)));
+
+        ArrayList<XmlSchemaTypeInfo> simpleExtensionUnion = new 
ArrayList<XmlSchemaTypeInfo>();
+        simpleExtensionUnion.add(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.BOOLEAN));
+        simpleExtensionUnion.add(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "simpleExtension"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(simpleExtensionUnion)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "simpleRestriction"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(simpleExtensionUnion)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "complexExtension"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "mixedType"),
+                             new ExpectedElement(new XmlSchemaTypeInfo(true)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "qName"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.QNAME)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "avroEnum"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.STRING)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "xmlEnum"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.STRING)));
+
+        expectedElements
+            .put(new QName(COMPLEX_SCHEMA_NS, "unsignedLongList"),
+                 new ExpectedElement(
+                                     new XmlSchemaTypeInfo(
+                                                           new 
XmlSchemaTypeInfo(
+                                                                               
  XmlSchemaBaseSimpleType.DECIMAL))));
+
+        ArrayList<XmlSchemaTypeInfo> listOfUnionTypes = new 
ArrayList<XmlSchemaTypeInfo>();
+        listOfUnionTypes.add(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.BOOLEAN));
+        listOfUnionTypes.add(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.STRING));
+        listOfUnionTypes.add(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+        listOfUnionTypes.add(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL));
+
+        expectedElements
+            .put(new QName(COMPLEX_SCHEMA_NS, "listOfUnion"),
+                 new ExpectedElement(new XmlSchemaTypeInfo(new 
XmlSchemaTypeInfo(listOfUnionTypes))));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "firstMap"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "value"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "secondMap"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(false)));
+
+        expectedElements.put(new QName(COMPLEX_SCHEMA_NS, "fixed"),
+                             new ExpectedElement(new 
XmlSchemaTypeInfo(XmlSchemaBaseSimpleType.DECIMAL)));
+
+        // No Children
+        SortedMap<Integer, ExpectedNode> noChildren = new TreeMap<Integer, 
ExpectedNode>();
+
+        // Leaf Nodes
+        ExpectedNode qName = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                              
Collections.singletonList(noChildren));
+        qName.setElemQName(new QName(COMPLEX_SCHEMA_NS, "qName"));
+
+        ExpectedNode avroEnum = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                                 
Collections.singletonList(noChildren));
+        avroEnum.setElemQName(new QName(COMPLEX_SCHEMA_NS, "avroEnum"));
+
+        ExpectedNode xmlEnum = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                                
Collections.singletonList(noChildren));
+        xmlEnum.setElemQName(new QName(COMPLEX_SCHEMA_NS, "xmlEnum"));
+
+        ArrayList<SortedMap<Integer, ExpectedNode>> xmlEnumMaxOccurs2Children 
= new ArrayList<SortedMap<Integer, ExpectedNode>>();
+        xmlEnumMaxOccurs2Children.add(noChildren);
+        xmlEnumMaxOccurs2Children.add(noChildren);
+
+        ExpectedNode xmlEnumMaxOccurs2 = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 2,
+                                                          
xmlEnumMaxOccurs2Children);
+        xmlEnumMaxOccurs2.setElemQName(new QName(COMPLEX_SCHEMA_NS, 
"xmlEnum"));
+
+        ExpectedNode unsignedLongList = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                                         
Collections.singletonList(noChildren));
+        unsignedLongList.setElemQName(new QName(COMPLEX_SCHEMA_NS, 
"unsignedLongList"));
+
+        ExpectedNode listOfUnion = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                                    
Collections.singletonList(noChildren));
+        listOfUnion.setElemQName(new QName(COMPLEX_SCHEMA_NS, "listOfUnion"));
+
+        ArrayList<SortedMap<Integer, ExpectedNode>> valueChildren = new 
ArrayList<SortedMap<Integer, ExpectedNode>>();
+        valueChildren.add(noChildren);
+        valueChildren.add(noChildren);
+
+        ExpectedNode value = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 2, valueChildren);
+        value.setElemQName(new QName(COMPLEX_SCHEMA_NS, "value"));
+
+        ExpectedNode fixed = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                              
Collections.singletonList(noChildren));
+        fixed.setElemQName(new QName(COMPLEX_SCHEMA_NS, "fixed"));
+
+        ExpectedNode any = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ANY, 1, 1,
+                                            
Collections.singletonList(noChildren));
+
+        // backtrack
+        SortedMap<Integer, ExpectedNode> backtrackSubSequenceChildren = new 
TreeMap<Integer, ExpectedNode>();
+        backtrackSubSequenceChildren.put(0, qName);
+        backtrackSubSequenceChildren.put(1, avroEnum);
+        backtrackSubSequenceChildren.put(2, xmlEnumMaxOccurs2);
+        backtrackSubSequenceChildren.put(3, unsignedLongList);
+        backtrackSubSequenceChildren.put(4, listOfUnion);
+
+        ExpectedNode backtrackSubSequence = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                             Collections
+                                                                 
.singletonList(backtrackSubSequenceChildren));
+
+        SortedMap<Integer, ExpectedNode> backtrackSequenceChildren = new 
TreeMap<Integer, ExpectedNode>();
+        backtrackSequenceChildren.put(1, backtrackSubSequence);
+
+        ExpectedNode backtrackSequence = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                          Collections
+                                                              
.singletonList(backtrackSequenceChildren));
+
+        SortedMap<Integer, ExpectedNode> backtrackChildren = new 
TreeMap<Integer, ExpectedNode>();
+        backtrackChildren.put(0, backtrackSequence);
+
+        ExpectedNode backtrack = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                                  
Collections.singletonList(backtrackChildren));
+        backtrack.setElemQName(new QName(COMPLEX_SCHEMA_NS, "backtrack"));
+
+        // allTheThings
+        SortedMap<Integer, ExpectedNode> firstMapSeqChildren = new 
TreeMap<Integer, ExpectedNode>();
+        firstMapSeqChildren.put(0, value);
+
+        ExpectedNode firstMapSequence = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                         
Collections.singletonList(firstMapSeqChildren));
+
+        SortedMap<Integer, ExpectedNode> firstMapChildren = new 
TreeMap<Integer, ExpectedNode>();
+        firstMapChildren.put(0, firstMapSequence);
+
+        ExpectedNode firstMap = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                                 
Collections.singletonList(firstMapChildren));
+        firstMap.setElemQName(new QName(COMPLEX_SCHEMA_NS, "firstMap"));
+
+        ExpectedNode secondMap = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                                  
Collections.singletonList(noChildren));
+        secondMap.setElemQName(new QName(COMPLEX_SCHEMA_NS, "secondMap"));
+
+        SortedMap<Integer, ExpectedNode> allGroupChildren = new 
TreeMap<Integer, ExpectedNode>();
+
+        allGroupChildren.put(0, firstMap);
+        allGroupChildren.put(1, secondMap);
+
+        ExpectedNode allGroup = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ALL, 1, 1,
+                                                 
Collections.singletonList(allGroupChildren));
+
+        SortedMap<Integer, ExpectedNode> allTheThingsChildren = new 
TreeMap<Integer, ExpectedNode>();
+        allTheThingsChildren.put(0, allGroup);
+
+        ExpectedNode allTheThings = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                                     
Collections.singletonList(allTheThingsChildren));
+        allTheThings.setElemQName(new QName(COMPLEX_SCHEMA_NS, 
"allTheThings"));
+
+        // prohibit
+        SortedMap<Integer, ExpectedNode> prohibitSeqChildren = new 
TreeMap<Integer, ExpectedNode>();
+        prohibitSeqChildren.put(0, fixed);
+
+        ExpectedNode prohibitSequence = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                         
Collections.singletonList(prohibitSeqChildren));
+
+        SortedMap<Integer, ExpectedNode> prohibitChildren = new 
TreeMap<Integer, ExpectedNode>();
+        prohibitChildren.put(0, prohibitSequence);
+
+        ExpectedNode prohibit = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                                 
Collections.singletonList(prohibitChildren));
+        prohibit.setElemQName(new QName(COMPLEX_SCHEMA_NS, "prohibit"));
+
+        // anyAndFriends
+        SortedMap<Integer, ExpectedNode> anyAndFriendsSeqChildren = new 
TreeMap<Integer, ExpectedNode>();
+        anyAndFriendsSeqChildren.put(0, any);
+        anyAndFriendsSeqChildren.put(1, any);
+        anyAndFriendsSeqChildren.put(2, any);
+        anyAndFriendsSeqChildren.put(3, any);
+        anyAndFriendsSeqChildren.put(4, any);
+        anyAndFriendsSeqChildren.put(5, any);
+
+        ExpectedNode anyAndFriendsSeq = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                         
Collections.singletonList(anyAndFriendsSeqChildren));
+
+        SortedMap<Integer, ExpectedNode> anyAndFriendsChildren = new 
TreeMap<Integer, ExpectedNode>();
+        anyAndFriendsChildren.put(0, anyAndFriendsSeq);
+
+        ExpectedNode anyAndFriends = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                                      
Collections.singletonList(anyAndFriendsChildren));
+        anyAndFriends.setElemQName(new QName(COMPLEX_SCHEMA_NS, 
"anyAndFriends"));
+
+        // simpleExtension
+        ExpectedNode simpleExtension = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 0, 1,
+                                                        
Collections.singletonList(noChildren));
+        simpleExtension.setElemQName(new QName(COMPLEX_SCHEMA_NS, 
"simpleExtension"));
+
+        // simpleRestriction
+        ExpectedNode simpleRestriction = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 0, 1,
+                                                          
Collections.singletonList(noChildren));
+        simpleRestriction.setElemQName(new QName(COMPLEX_SCHEMA_NS, 
"simpleRestriction"));
+
+        // complexExtension
+        SortedMap<Integer, ExpectedNode> complexExtensionSubSequenceChildren = 
new TreeMap<Integer, ExpectedNode>();
+        complexExtensionSubSequenceChildren.put(0, fixed);
+
+        ExpectedNode complexExtensionSubSequence = new ExpectedNode(
+                                                                    
XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                    1,
+                                                                    1,
+                                                                    Collections
+                                                                        
.singletonList(complexExtensionSubSequenceChildren));
+
+        SortedMap<Integer, ExpectedNode> complexExtensionSubChoiceChildren = 
new TreeMap<Integer, ExpectedNode>();
+        complexExtensionSubChoiceChildren.put(1, unsignedLongList);
+
+        ExpectedNode complexExtensionSubChoice = new ExpectedNode(
+                                                                  
XmlSchemaStateMachineNode.Type.CHOICE,
+                                                                  1,
+                                                                  1,
+                                                                  Collections
+                                                                      
.singletonList(complexExtensionSubChoiceChildren));
+
+        SortedMap<Integer, ExpectedNode> complexExtensionSequenceChildren = 
new TreeMap<Integer, ExpectedNode>();
+        complexExtensionSequenceChildren.put(0, complexExtensionSubSequence);
+        complexExtensionSequenceChildren.put(1, complexExtensionSubChoice);
+
+        ExpectedNode complexExtensionSequence = new ExpectedNode(
+                                                                 
XmlSchemaStateMachineNode.Type.SEQUENCE,
+                                                                 1,
+                                                                 1,
+                                                                 Collections
+                                                                     
.singletonList(complexExtensionSequenceChildren));
+
+        SortedMap<Integer, ExpectedNode> complexExtensionChildren = new 
TreeMap<Integer, ExpectedNode>();
+        complexExtensionChildren.put(0, complexExtensionSequence);
+
+        ExpectedNode complexExtension = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 0, 1,
+                                                         
Collections.singletonList(complexExtensionChildren));
+        complexExtension.setElemQName(new QName(COMPLEX_SCHEMA_NS, 
"complexExtension"));
+
+        // mixedType
+        SortedMap<Integer, ExpectedNode> mixedTypeSeqChildren = new 
TreeMap<Integer, ExpectedNode>();
+        mixedTypeSeqChildren.put(0, listOfUnion);
+        mixedTypeSeqChildren.put(1, unsignedLongList);
+
+        ExpectedNode mixedTypeSeq = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                     
Collections.singletonList(mixedTypeSeqChildren));
+
+        SortedMap<Integer, ExpectedNode> mixedTypeChildren = new 
TreeMap<Integer, ExpectedNode>();
+        mixedTypeChildren.put(0, mixedTypeSeq);
+
+        ExpectedNode mixedType = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 0, 1,
+                                                  
Collections.singletonList(mixedTypeChildren));
+        mixedType.setElemQName(new QName(COMPLEX_SCHEMA_NS, "mixedType"));
+
+        // realRoot
+        SortedMap<Integer, ExpectedNode> realRootSequenceChildren = new 
TreeMap<Integer, ExpectedNode>();
+
+        realRootSequenceChildren.put(0, backtrack);
+        realRootSequenceChildren.put(1, allTheThings);
+        realRootSequenceChildren.put(2, prohibit);
+        realRootSequenceChildren.put(3, anyAndFriends);
+        realRootSequenceChildren.put(4, simpleExtension);
+        realRootSequenceChildren.put(5, simpleRestriction);
+        realRootSequenceChildren.put(6, complexExtension);
+        realRootSequenceChildren.put(7, mixedType);
+
+        ExpectedNode realRootSequence = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SEQUENCE, 1, 1,
+                                                         
Collections.singletonList(realRootSequenceChildren));
+
+        SortedMap<Integer, ExpectedNode> realRootChildren = new 
TreeMap<Integer, ExpectedNode>();
+        realRootChildren.put(0, realRootSequence);
+
+        ExpectedNode realRoot = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.ELEMENT, 1, 1,
+                                                 
Collections.singletonList(realRootChildren));
+        realRoot.setElemQName(new QName(COMPLEX_SCHEMA_NS, "realRoot"));
+
+        SortedMap<Integer, ExpectedNode> rootSubstGrpChildren = new 
TreeMap<Integer, ExpectedNode>();
+        rootSubstGrpChildren.put(0, realRoot);
+
+        ExpectedNode rootSubstGrp = new 
ExpectedNode(XmlSchemaStateMachineNode.Type.SUBSTITUTION_GROUP, 1, 1,
+                                                     
Collections.singletonList(rootSubstGrpChildren));
+
+        ExpectedNode.validate(COMPLEX_SCHEMA_NS, rootSubstGrp, 
traversal.getDocumentNode(), expectedElements);
+
+        ArrayList<ExpectedPathNode> expPath = new 
ArrayList<ExpectedPathNode>();
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
rootSubstGrp, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
realRoot, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
realRootSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
backtrack, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
backtrackSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
backtrackSubSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
qName, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
qName, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
backtrackSubSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
avroEnum, 1));
+
+        // Path Index 10
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
avroEnum, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
backtrackSubSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
xmlEnumMaxOccurs2, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
xmlEnumMaxOccurs2, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
xmlEnumMaxOccurs2, 2));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
xmlEnumMaxOccurs2, 2));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
backtrackSubSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
unsignedLongList, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
unsignedLongList, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
backtrackSubSequence, 1));
+
+        // Path Index 20
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
listOfUnion, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
listOfUnion, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
backtrackSubSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
backtrackSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
backtrack, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
realRootSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
allTheThings, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
allGroup, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
secondMap, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
allGroup, 1));
+
+        // Path Index 30
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
firstMap, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
firstMapSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
value, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.SIBLING, 
value, 2));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
firstMapSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
firstMap, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
allGroup, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
allTheThings, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
realRootSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
prohibit, 1));
+
+        // Path Index 40
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
prohibitSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
fixed, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
prohibitSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
prohibit, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
realRootSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
anyAndFriends, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
anyAndFriends, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
anyAndFriendsSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
any, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
anyAndFriendsSeq, 1));
+
+        // Path Index 50
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
anyAndFriendsSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
any, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
anyAndFriendsSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
anyAndFriendsSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
any, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
anyAndFriendsSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
anyAndFriendsSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
any, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
anyAndFriendsSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
anyAndFriendsSeq, 1));
+
+        // Path Index 60
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
any, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
anyAndFriendsSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
anyAndFriendsSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
any, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
anyAndFriendsSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
anyAndFriends, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
anyAndFriends, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
realRootSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
simpleExtension, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
simpleExtension, 1));
+
+        // Path Index 70
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
realRootSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
simpleRestriction, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
simpleRestriction, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
realRootSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
complexExtension, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
complexExtensionSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
complexExtensionSubSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
fixed, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
complexExtensionSubSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
complexExtensionSequence, 1));
+
+        // Path Index 80
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
complexExtensionSubChoice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
unsignedLongList, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
unsignedLongList, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
complexExtensionSubChoice, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
complexExtensionSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
complexExtension, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
realRootSequence, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
mixedType, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
mixedType, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
mixedTypeSeq, 1));
+
+        // Path Index 90
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
listOfUnion, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
listOfUnion, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
mixedTypeSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
mixedTypeSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CHILD, 
unsignedLongList, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
unsignedLongList, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
mixedTypeSeq, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
mixedType, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.CONTENT, 
mixedType, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
realRootSequence, 1));
+
+        // Path Index 100
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
realRoot, 1));
+
+        expPath.add(new ExpectedPathNode(XmlSchemaPathNode.Direction.PARENT, 
rootSubstGrp, 1));
+
+        validate(expPath, traversal);
+    }
+
+    private XmlSchemaPathNode runTest(File schemaFile, File xmlFile, QName 
root) throws Exception {
+
+        XmlSchemaCollection xmlSchemaCollection = new XmlSchemaCollection();
+
+        FileReader schemaFileReader = null;
+        try {
+            schemaFileReader = new FileReader(schemaFile);
+            xmlSchemaCollection.read(new StreamSource(schemaFileReader));
+        } finally {
+            if (schemaFileReader != null) {
+                schemaFileReader.close();
+            }
+        }
+
+        return runTest(xmlSchemaCollection, xmlFile, root);
+    }
+
+    private XmlSchemaPathNode runTest(XmlSchemaCollection xmlSchemaCollection, 
File xmlFile, QName root)
+        throws Exception {
+
+        XmlSchemaStateMachineGenerator stateMachineGen = new 
XmlSchemaStateMachineGenerator();
+
+        XmlSchemaWalker walker = new XmlSchemaWalker(xmlSchemaCollection, 
stateMachineGen);
+
+        XmlSchemaElement rootElement = 
xmlSchemaCollection.getElementByQName(root);
+
+        walker.walk(rootElement);
+
+        XmlSchemaStateMachineNode stateMachine = 
stateMachineGen.getStartNode();
+
+        XmlSchemaPathFinder pathFinder = new XmlSchemaPathFinder(stateMachine);
+
+        Document xmlDoc = docBuilder.parse(xmlFile);
+
+        SaxWalkerOverDom saxWalker = new SaxWalkerOverDom(pathFinder);
+
+        saxWalker.walk(xmlDoc);
+
+        return pathFinder.getXmlSchemaTraversal();
+    }
+
+    void validate(ArrayList<ExpectedPathNode> expPath, XmlSchemaPathNode 
start) {
+        XmlSchemaPathNode prev = null;
+        XmlSchemaPathNode curr = start;
+        int position = 0;
+
+        do {
+            assertTrue("Expected Path Too Short (position " + position + " >= 
expected " + expPath.size()
+                       + ")", expPath.size() > position);
+
+            assertEquals("Path Index " + position + "; prev != 
curr.getPrevious()", prev, curr.getPrevious());
+
+            expPath.get(position).validate(position, curr);
+
+            prev = curr;
+            curr = curr.getNext();
+            ++position;
+        } while (curr != null);
+
+        assertEquals(expPath.size(), position);
+    }
+}

Propchange: 
webservices/xmlschema/trunk/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/docpath/TestXmlSchemaPathFinder.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to