XMLSCHEMA-56 - Element defined in a base type sometimes isn't visited by an XmlSchemaWalker's visitor. Thanks to kgi. This closes #4.
diff --git a/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/SchemasByNamespace.java b/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/SchemasByNamespace.java
new file mode 100644
index 0000000..b2b54a6
--- /dev/null
+++ b/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/SchemasByNamespace.java
@@ -0,0 +1,210 @@
+/**
+ * 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.walker;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaAttribute;
+import org.apache.ws.commons.schema.XmlSchemaAttributeGroup;
+import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.XmlSchemaGroup;
+import org.apache.ws.commons.schema.XmlSchemaType;
+
+/**
+ * A class that allows XmlSchemas to be stored, indexed by a String which is the schema's target namespace.
+ * Multiple schemas are allowed for each namespace.
+ * It provides methods that allow all schemas for a given namespace to be searched, for example when the caller
+ * wishes to find an xsd type defined for a particular namespace.
+ **/
+class SchemasByNamespace {
+
+ /**
+ * the map of namespaces to a list of XmlSchemas
+ */
+ private final Map<String, List<XmlSchema>> mData = new HashMap<String, List<XmlSchema>>();
+
+ /**
+ * Associates an XmlSchema with a namespace
+ * @param aNamespace the namespace in question
+ * @param aSchema a schema with aNamespace as its target
+ */
+ public void addSchema(String aNamespace, XmlSchema aSchema) {
+ if (aNamespace == null) {
+ aNamespace = "";
+ }
+ List<XmlSchema> value = mData.get(aNamespace);
+ if (value == null) {
+ value = new ArrayList<XmlSchema>();
+ mData.put(aNamespace, value);
+ }
+ value.add(aSchema);
+ }
+
+ /**
+ * Returns a List of XmlSchemas that have been associated with the given namespace using addSchema(...).
+ * @param aNamespace the namespace in question
+ * @return a List of XmlSchemas which target aNamespace
+ */
+ public XmlSchema[] getSchemas(String aNamespace) {
+ if (aNamespace == null) {
+ aNamespace = "";
+ }
+ List<XmlSchema> l = mData.get(aNamespace);
+ return l == null ? new XmlSchema[0] : l.toArray(new XmlSchema[l.size()]);
+ }
+
+ /**
+ * Returns an XmlSchemaType with the given QName.
+ * The namespace defined by the name is used to find the schema in which the type is defined, and thus the type itself.
+ * @param aTypeName the name of the type, which must return the correct value for aTypeName.getNamespaceURI().
+ * @return the XmlSchemaType with name aTypeName or null if no such type is found
+ */
+ public XmlSchemaType getTypeByName(QName aTypeName) {
+ XmlSchema[] schemas = getSchemas(aTypeName.getNamespaceURI());
+ for (XmlSchema s : schemas) {
+ XmlSchemaType t = s.getTypeByName(aTypeName);
+ if (t != null) {
+ return t;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns an XmlSchemaGroup with the given QName.
+ * The namespace defined by the name is used to find the schema in which the group is defined, and thus the group itself.
+ * @param aGroupName the name of the group, which must return the correct value for aGroupName.getNamespaceURI().
+ * @return the XmlSchemaGroup with name aGroupName or null if no such group is found
+ */
+ public XmlSchemaGroup getGroupByName(QName aGroupName) {
+ XmlSchema[] schemas = getSchemas(aGroupName.getNamespaceURI());
+ for (XmlSchema s : schemas) {
+ XmlSchemaGroup g = s.getGroupByName(aGroupName);
+ if (g != null) {
+ return g;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns an XmlSchemaAttribute with the given QName.
+ * The namespace defined by the name is used to find the schema in which the attribute is defined, and thus the attribute itself.
+ * @param aAttName the name of the attribute, which must return the correct value for aAttName.getNamespaceURI().
+ * @return the XmlSchemaAttribute with name aAttName or null if no such attribute is found
+ */
+ public XmlSchemaAttribute getAttributeByName(QName aAttName) {
+ XmlSchema[] schemas = getSchemas(aAttName.getNamespaceURI());
+ for (XmlSchema s : schemas) {
+ XmlSchemaAttribute a = s.getAttributeByName(aAttName);
+ if (a != null) {
+ return a;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns an XmlSchemaAttributeGroup with the given QName.
+ * The namespace defined by the name is used to find the schema in which the attribute group is defined, and thus the attribute group itself.
+ * @param aAGName the name of the attribute group, which must return the correct value for aAGName.getNamespaceURI().
+ * @return the XmlSchemaAttributeGroup with name aAGName or null if no such attribute group is found
+ */
+ public XmlSchemaAttributeGroup getAttributeGroupByName(QName aAGName) {
+ XmlSchema[] schemas = getSchemas(aAGName.getNamespaceURI());
+ for (XmlSchema s : schemas) {
+ XmlSchemaAttributeGroup ag = s.getAttributeGroupByName(aAGName);
+ if (ag != null) {
+ return ag;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns an XmlSchemaElement with the given QName.
+ * The namespace defined by the name is used to find the schema in which the element is defined, and thus the element itself.
+ * @param aElementName the name of the element, which must return the correct value for aElementName.getNamespaceURI().
+ * @return the XmlSchemaElement with name aElementName or null if no such element is found
+ */
+ public XmlSchemaElement getElementByName(QName aElementName) {
+ XmlSchema[] schemas = getSchemas(aElementName.getNamespaceURI());
+ for (XmlSchema s : schemas) {
+ XmlSchemaElement e = s.getElementByName(aElementName);
+ if (e != null) {
+ return e;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns an XmlSchema which includes an element with the given QName.
+ * The namespace defined by the name is used to find the schema in which the element is defined.
+ * @param aElementName the name of the element, which must return the correct value for aElementName.getNamespaceURI().
+ * @return the XmlSchema which includes the element with name aElementName or null if no such schema is found
+ */
+ public XmlSchema getSchemaDefiningElement(QName aElementName) {
+ XmlSchema[] schemas = getSchemas(aElementName.getNamespaceURI());
+ for (XmlSchema s : schemas) {
+ XmlSchemaElement e = s.getElementByName(aElementName);
+ if (e != null) {
+ return s;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns an XmlSchema which includes an attribute with the given QName.
+ * The namespace defined by the name is used to find the schema in which the attribute is defined.
+ * @param aAttName the name of the attribute, which must return the correct value for aAttName.getNamespaceURI().
+ * @return the XmlSchema which includes the attribute with name aAttName or null if no such schema is found
+ */
+ public XmlSchema getSchemaDefiningAttribute(QName aAttName) {
+ XmlSchema[] schemas = getSchemas(aAttName.getNamespaceURI());
+ for (XmlSchema s : schemas) {
+ XmlSchemaAttribute a = s.getAttributeByName(aAttName);
+ if (a != null) {
+ return s;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Returns the first XmlSchema added with the given namespace, using addSchema(...)
+ * @param aNamespace the namespace in question
+ * @return the XmlSchema first added with aNamespace
+ */
+ public XmlSchema getFirstSchema(String aNamespace) {
+ XmlSchema[] schemas = getSchemas(aNamespace);
+ if (schemas.length > 0) {
+ return schemas[0];
+ } else {
+ return null;
+ }
+ }
+}
diff --git a/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaScope.java b/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaScope.java
index 34e0343..f87c1dc 100644
--- a/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaScope.java
+++ b/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaScope.java
@@ -63,7 +63,7 @@
*/
final class XmlSchemaScope {
- private Map<String, XmlSchema> schemasByNamespace;
+ private SchemasByNamespace schemasByNamespace;
private Map<QName, XmlSchemaScope> scopeCache;
private XmlSchemaTypeInfo typeInfo;
@@ -100,7 +100,7 @@
* @param substitutions The master list of substitution groups to pull from.
* @param userRecognizedTypes The set of types recognized by the caller.
*/
- XmlSchemaScope(XmlSchemaType type, Map<String, XmlSchema> xmlSchemasByNamespace,
+ XmlSchemaScope(XmlSchemaType type, SchemasByNamespace xmlSchemasByNamespace,
Map<QName, XmlSchemaScope> scopeCache, Set<QName> userRecognizedTypes) {
this();
@@ -169,9 +169,7 @@
XmlSchemaSimpleTypeList list = (XmlSchemaSimpleTypeList)content;
XmlSchemaSimpleType listType = list.getItemType();
if (listType == null) {
- XmlSchema schema = schemasByNamespace.get(list.getItemTypeName().getNamespaceURI());
-
- listType = (XmlSchemaSimpleType)schema.getTypeByName(list.getItemTypeName());
+ listType = (XmlSchemaSimpleType)schemasByNamespace.getTypeByName(list.getItemTypeName());
}
if (listType == null) {
throw new IllegalArgumentException("Unrecognized schema type for list "
@@ -202,8 +200,7 @@
}
for (QName namedBaseType : namedBaseTypes) {
- XmlSchema schema = schemasByNamespace.get(namedBaseType.getNamespaceURI());
- XmlSchemaSimpleType baseType = (XmlSchemaSimpleType)schema.getTypeByName(namedBaseType);
+ XmlSchemaSimpleType baseType = (XmlSchemaSimpleType)schemasByNamespace.getTypeByName(namedBaseType);
if (baseType != null) {
baseTypes.add(baseType);
}
@@ -247,8 +244,7 @@
} else {
XmlSchemaSimpleType baseType = restr.getBaseType();
if (baseType == null) {
- XmlSchema schema = schemasByNamespace.get(restr.getBaseTypeName().getNamespaceURI());
- baseType = (XmlSchemaSimpleType)schema.getTypeByName(restr.getBaseTypeName());
+ baseType = (XmlSchemaSimpleType)schemasByNamespace.getTypeByName(restr.getBaseTypeName());
}
if (baseType != null) {
@@ -323,8 +319,7 @@
if (content instanceof XmlSchemaComplexContentExtension) {
XmlSchemaComplexContentExtension ext = (XmlSchemaComplexContentExtension)content;
- XmlSchema schema = schemasByNamespace.get(ext.getBaseTypeName().getNamespaceURI());
- XmlSchemaType baseType = schema.getTypeByName(ext.getBaseTypeName());
+ XmlSchemaType baseType = schemasByNamespace.getTypeByName(ext.getBaseTypeName());
XmlSchemaParticle baseParticle = null;
XmlSchemaAnyAttribute baseAnyAttr = null;
@@ -418,9 +413,7 @@
} else if (content instanceof XmlSchemaComplexContentRestriction) {
final XmlSchemaComplexContentRestriction rstr = (XmlSchemaComplexContentRestriction)content;
- final XmlSchema schema = schemasByNamespace.get(rstr.getBaseTypeName().getNamespaceURI());
-
- final XmlSchemaType baseType = schema.getTypeByName(rstr.getBaseTypeName());
+ final XmlSchemaType baseType = schemasByNamespace.getTypeByName(rstr.getBaseTypeName());
XmlSchemaScope parentScope = null;
if (baseType != null) {
@@ -460,8 +453,7 @@
XmlSchemaSimpleContentExtension ext = (XmlSchemaSimpleContentExtension)content;
attributes = createAttributeMap(ext.getAttributes());
- XmlSchema schema = schemasByNamespace.get(ext.getBaseTypeName().getNamespaceURI());
- XmlSchemaType baseType = schema.getTypeByName(ext.getBaseTypeName());
+ XmlSchemaType baseType = schemasByNamespace.getTypeByName(ext.getBaseTypeName());
if (baseType != null) {
final XmlSchemaScope parentScope = getScope(baseType);
@@ -484,8 +476,7 @@
if (rstr.getBaseType() != null) {
baseType = rstr.getBaseType();
} else {
- XmlSchema schema = schemasByNamespace.get(rstr.getBaseTypeName().getNamespaceURI());
- baseType = schema.getTypeByName(rstr.getBaseTypeName());
+ baseType = schemasByNamespace.getTypeByName(rstr.getBaseTypeName());
}
if (baseType != null) {
@@ -505,8 +496,7 @@
XmlSchemaAttributeGroup attrGroup = groupRef.getRef().getTarget();
if (attrGroup == null) {
- XmlSchema schema = schemasByNamespace.get(groupRef.getTargetQName().getNamespaceURI());
- attrGroup = schema.getAttributeGroupByName(groupRef.getTargetQName());
+ attrGroup = schemasByNamespace.getAttributeGroupByName(groupRef.getTargetQName());
}
return getAttributesOf(attrGroup);
}
@@ -556,7 +546,6 @@
} else {
attrQName = attribute.getQName();
}
- final XmlSchema schema = schemasByNamespace.get(attrQName.getNamespaceURI());
if (!attribute.isRef() && (forceCopy || (attribute.getSchemaType() == null))) {
// If we are forcing a copy, there is no reference to follow.
@@ -565,7 +554,7 @@
if (attribute.getRef().getTarget() != null) {
globalAttr = attribute.getRef().getTarget();
} else {
- globalAttr = schema.getAttributeByName(attrQName);
+ globalAttr = schemasByNamespace.getAttributeByName(attrQName);
}
}
@@ -573,8 +562,7 @@
if (schemaType == null) {
final QName typeQName = globalAttr.getSchemaTypeName();
if (typeQName != null) {
- XmlSchema typeSchema = schemasByNamespace.get(typeQName.getNamespaceURI());
- schemaType = (XmlSchemaSimpleType) typeSchema.getTypeByName(typeQName);
+ schemaType = (XmlSchemaSimpleType) schemasByNamespace.getTypeByName(typeQName);
}
}
@@ -603,6 +591,12 @@
attrUsage = XmlSchemaUse.OPTIONAL;
}
+ XmlSchema schema = schemasByNamespace.getSchemaDefiningAttribute(attrQName);
+ if (schema == null) {
+ // TODO: is this correct? The previous code used whichever schema was stored in the schemasByNamespace HashMap
+ // for the attribute's namespace.
+ schema = attribute.getParent();
+ }
final XmlSchemaAttribute copy = new XmlSchemaAttribute(schema, false);
copy.setName(globalAttr.getName());
@@ -788,7 +782,7 @@
return childFacets;
}
- HashMap<XmlSchemaRestriction.Type, List<XmlSchemaRestriction>> mergedFacets
+ HashMap<XmlSchemaRestriction.Type, List<XmlSchemaRestriction>> mergedFacets
= new HashMap<XmlSchemaRestriction.Type, List<XmlSchemaRestriction>>(parentFacets);
// Child facets override parent facets
diff --git a/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaWalker.java b/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaWalker.java
index 1b790b0..3251687 100644
--- a/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaWalker.java
+++ b/xmlschema-walker/src/main/java/org/apache/ws/commons/schema/walker/XmlSchemaWalker.java
@@ -53,9 +53,9 @@
private Set<QName> userRecognizedTypes;
private final XmlSchemaCollection schemas;
- private final ArrayList<XmlSchemaVisitor> visitors;
+ private final List<XmlSchemaVisitor> visitors;
private final Map<QName, List<XmlSchemaElement>> elemsBySubstGroup;
- private final Map<String, XmlSchema> schemasByNamespace;
+ private final SchemasByNamespace schemasByNamespace;
private final Map<QName, XmlSchemaScope> scopeCache;
private final Set<QName> visitedElements;
@@ -72,11 +72,11 @@
schemas = xmlSchemas;
visitors = new ArrayList<XmlSchemaVisitor>(1);
- schemasByNamespace = new HashMap<String, XmlSchema>();
+ schemasByNamespace = new SchemasByNamespace();
elemsBySubstGroup = new HashMap<QName, List<XmlSchemaElement>>();
for (XmlSchema schema : schemas.getXmlSchemas()) {
- schemasByNamespace.put(schema.getTargetNamespace(), schema);
+ schemasByNamespace.addSchema(schema.getTargetNamespace(), schema);
for (XmlSchemaElement elem : schema.getElements().values()) {
if (elem.getSubstitutionGroup() != null) {
@@ -211,8 +211,7 @@
if (schemaType == null) {
final QName typeQName = element.getSchemaTypeName();
if (typeQName != null) {
- XmlSchema schema = schemasByNamespace.get(typeQName.getNamespaceURI());
- schemaType = schema.getTypeByName(typeQName);
+ schemaType = schemasByNamespace.getTypeByName(typeQName);
}
}
@@ -233,7 +232,7 @@
// 2. for each visitor, call visitor.startElement(element, type);
final boolean previouslyVisited = (!element.isAnonymous() && visitedElements.contains(element
- .getQName()));
+ .getQName()));
for (XmlSchemaVisitor visitor : visitors) {
visitor.onEnterElement(element, typeInfo, previouslyVisited);
@@ -308,7 +307,7 @@
} else if (!element.isAbstract()) {
throw new IllegalStateException("Element " + element.getQName()
- + " is not abstract and has no type.");
+ + " is not abstract and has no type.");
}
// 8. Now handle substitute elements, if any.
@@ -328,9 +327,10 @@
XmlSchemaGroupRef groupRef = (XmlSchemaGroupRef)particle;
XmlSchemaGroupParticle group = groupRef.getParticle();
if (group == null) {
- XmlSchema schema = schemasByNamespace.get(groupRef.getRefName().getNamespaceURI());
-
- group = schema.getGroupByName(groupRef.getRefName()).getParticle();
+ XmlSchemaGroup g = schemasByNamespace.getGroupByName(groupRef.getRefName());
+ if (g != null) {
+ group = g.getParticle();
+ }
}
walk(group, groupRef.getMinOccurs(), groupRef.getMaxOccurs());
@@ -375,7 +375,7 @@
} else {
throw new IllegalArgumentException("Unrecognized XmlSchemaGroupParticle of type "
- + group.getClass().getName());
+ + group.getClass().getName());
}
// 2. Make a copy if necessary.
@@ -515,7 +515,6 @@
}
final QName elemQName = getElementQName(element);
- final XmlSchema schema = schemasByNamespace.get(elemQName.getNamespaceURI());
XmlSchemaElement globalElem = null;
if (!element.isRef()) {
@@ -523,7 +522,7 @@
} else if (element.getRef().getTarget() != null) {
globalElem = element.getRef().getTarget();
} else {
- globalElem = schema.getElementByName(elemQName);
+ globalElem = schemasByNamespace.getElementByName(elemQName);
}
/*
@@ -536,6 +535,13 @@
id = globalElem.getId();
}
+ XmlSchema schema = schemasByNamespace.getSchemaDefiningElement(elemQName);
+ if (schema == null) {
+ // TODO: is this correct? The previous code used whichever schema was stored in the schemasByNamespace HashMap
+ // for the element's namespace.
+ schema = element.getParent();
+ }
+
final XmlSchemaElement copy = new XmlSchemaElement(schema, false);
copy.setName(globalElem.getName());
copy.setAbstract(globalElem.isAbstract());
diff --git a/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestMultipleFilesPerNamespace.java b/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestMultipleFilesPerNamespace.java
new file mode 100644
index 0000000..166fd58
--- /dev/null
+++ b/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestMultipleFilesPerNamespace.java
@@ -0,0 +1,207 @@
+/**
+ * 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.walker;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.ws.commons.schema.XmlSchema;
+import org.apache.ws.commons.schema.XmlSchemaAll;
+import org.apache.ws.commons.schema.XmlSchemaAny;
+import org.apache.ws.commons.schema.XmlSchemaAnyAttribute;
+import org.apache.ws.commons.schema.XmlSchemaChoice;
+import org.apache.ws.commons.schema.XmlSchemaCollection;
+import org.apache.ws.commons.schema.XmlSchemaElement;
+import org.apache.ws.commons.schema.XmlSchemaSequence;
+import org.apache.ws.commons.schema.testutils.UtilsForTests;
+import org.junit.Test;
+
+public class TestMultipleFilesPerNamespace {
+
+ @Test
+ public void testMultipleFilesPerNamespace() throws Exception {
+ List<String> expected = new ArrayList<String>();
+ expected.add("{http://avro.apache.org/AvroTest}root");
+ expected.add("{http://avro.apache.org/AvroTest}baseElement");
+ expected.add("{http://avro.apache.org/AvroTest}includedType");
+ expected.add("{http://avro.apache.org/AvroTest}includedElement");
+ expected.add("{http://avro.apache.org/AvroTest}differentNamespaceType");
+ expected.add("{http://avro.apache.org/AvroTest2}differentNamespaceElement");
+ expected.add("{http://avro.apache.org/AvroTest}noNamespaceType");
+ expected.add("noNSElement");
+
+ MyVisitor v = new MyVisitor(expected);
+
+ XmlSchemaCollection collection = null;
+ FileReader fileReader = null;
+ try {
+ File file = UtilsForTests.buildFile("src", "test", "resources", "test_multiple_files_per_namespace.xsd");
+ fileReader = new FileReader(file);
+
+ collection = new XmlSchemaCollection();
+ collection.read(new StreamSource(fileReader, file.getAbsolutePath()));
+
+ } finally {
+ if (fileReader != null) {
+ try {
+ fileReader.close();
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+ }
+
+ XmlSchemaElement elem = getElementOf(collection, "root");
+ XmlSchemaWalker walker = new XmlSchemaWalker(collection, v);
+ try {
+ walker.walk(elem);
+ } catch (Exception e) {
+ throw new IllegalStateException(e.getMessage());
+ }
+
+
+ int pos = v.getNextExpectedPosition();
+ if (pos != expected.size()) {
+ throw new IllegalStateException("expected a further element");
+ }
+ }
+
+ class MyVisitor implements XmlSchemaVisitor {
+ List<String> mExpectedElements = null;
+ int mListPos = 0;
+
+ public MyVisitor(List<String> aExpectedElements) {
+ mExpectedElements = aExpectedElements;
+ }
+
+ public int getNextExpectedPosition () {
+ return mListPos;
+ }
+
+ @Override
+ public void onEnterElement(XmlSchemaElement element, XmlSchemaTypeInfo typeInfo, boolean previouslyVisited) {
+ // TODO Auto-generated method stub
+ if (mListPos >= mExpectedElements.size()) {
+ throw new IllegalStateException("unexpected element");
+ }
+ String expected = mExpectedElements.get(mListPos++);
+ if (!element.getQName().toString().equals(expected)) {
+ throw new IllegalStateException("incorrect element");
+ }
+ }
+
+ @Override
+ public void onExitElement(XmlSchemaElement element, XmlSchemaTypeInfo typeInfo, boolean previouslyVisited) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onVisitAttribute(XmlSchemaElement element, XmlSchemaAttrInfo attrInfo) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onEndAttributes(XmlSchemaElement element, XmlSchemaTypeInfo typeInfo) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onEnterSubstitutionGroup(XmlSchemaElement base) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onExitSubstitutionGroup(XmlSchemaElement base) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onEnterAllGroup(XmlSchemaAll all) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onExitAllGroup(XmlSchemaAll all) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onEnterChoiceGroup(XmlSchemaChoice choice) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onExitChoiceGroup(XmlSchemaChoice choice) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onEnterSequenceGroup(XmlSchemaSequence seq) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onExitSequenceGroup(XmlSchemaSequence seq) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onVisitAny(XmlSchemaAny any) {
+ // TODO Auto-generated method stub
+
+ }
+
+ @Override
+ public void onVisitAnyAttribute(XmlSchemaElement element, XmlSchemaAnyAttribute anyAttr) {
+ // TODO Auto-generated method stub
+
+ }
+
+ }
+
+ private static XmlSchemaElement getElementOf(XmlSchemaCollection collection, String name) {
+
+ XmlSchemaElement elem = null;
+ XmlSchema[] schemas = collection.getXmlSchemas();
+ for (XmlSchema schema : schemas) {
+ elem = schema.getElementByName(name);
+ if (elem != null) {
+ break;
+ }
+ }
+ return elem;
+ }
+}
+
diff --git a/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java b/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java
index 51ef535..c4ab3b4 100644
--- a/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java
+++ b/xmlschema-walker/src/test/java/org/apache/ws/commons/schema/walker/TestSchemaWalker.java
@@ -498,12 +498,7 @@
private HashMap<String, List<Attribute>> attributes;
}
- /**
- * Test for src/main/resources/test_schema.xsd
- */
- @SuppressWarnings("unchecked")
- @Test
- public void test() throws Exception {
+ public void test(File aFile) throws Exception {
// Build the expectations.
ArrayList<Attribute> attrGroupAttrs = new ArrayList<Attribute>(43);
@@ -856,11 +851,10 @@
XmlSchemaCollection collection = null;
FileReader fileReader = null;
try {
- File file = UtilsForTests.buildFile("src", "test", "resources", "test_schema.xsd");
- fileReader = new FileReader(file);
+ fileReader = new FileReader(aFile);
collection = new XmlSchemaCollection();
- collection.read(new StreamSource(fileReader, file.getAbsolutePath()));
+ collection.read(new StreamSource(fileReader, aFile.getAbsolutePath()));
} finally {
if (fileReader != null) {
@@ -883,6 +877,24 @@
Assert.assertTrue(stack.isEmpty());
}
+ /**
+ * test for test_schema.xsd
+ */
+ @Test
+ public void testSchemaWalker() throws Exception {
+ File file = UtilsForTests.buildFile("src", "test", "resources", "test_schema.xsd");
+ test(file);
+ }
+
+ /**
+ * test for test_multiple_files_per_namespace2.xsd, which is test_schema.xsd distributed between three files
+ */
+ @Test
+ public void testMultipleFilesPerNamespace2() throws Exception {
+ File file = UtilsForTests.buildFile("src", "test", "resources", "test_multiple_files_per_namespace2.xsd");
+ test(file);
+ }
+
private static void checkFacets(String nextName, XmlSchemaTypeInfo typeInfo,
Set<XmlSchemaRestriction> nextFacets) {
if (typeInfo == null) {
diff --git a/xmlschema-walker/src/test/resources/test_mfpn2_included1.xsd b/xmlschema-walker/src/test/resources/test_mfpn2_included1.xsd
new file mode 100644
index 0000000..7ae2523
--- /dev/null
+++ b/xmlschema-walker/src/test/resources/test_mfpn2_included1.xsd
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<!--
+ This file is included by test_multiple_files_per_namespace2.xsd
+ -->
+ <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://avro.apache.org/AvroTest" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:avro="http://avro.apache.org/AvroTest">
+
+ <xsd:attributeGroup name="attrGroup" id="attrGroup">
+ <xsd:annotation>
+ <xsd:documentation>An attribute group with attributes of all simple types.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:attribute name="anySimpleType" type="xsd:anySimpleType" use="optional" />
+ <xsd:attribute name="duration" type="xsd:duration" use="optional" />
+ <xsd:attribute name="dateTime" type="xsd:dateTime" use="optional" />
+ <xsd:attribute name="date" type="xsd:date" use="optional" />
+ <xsd:attribute name="time" type="xsd:time" use="optional" />
+ <xsd:attribute name="gYearMonth" type="xsd:gYearMonth" use="optional" />
+ <xsd:attribute name="gYear" type="xsd:gYear" use="optional" />
+ <xsd:attribute name="gMonthDay" type="xsd:gMonthDay" use="optional" />
+ <xsd:attribute name="gDay" type="xsd:gDay" use="optional" />
+ <xsd:attribute name="gMonth" type="xsd:gMonth" use="optional" />
+ <xsd:attribute name="string" type="xsd:string" use="optional" />
+ <xsd:attribute name="boolean" type="xsd:boolean" use="optional" />
+ <xsd:attribute name="base64Binary" type="xsd:base64Binary" use="optional" />
+ <xsd:attribute name="hexBinary" type="xsd:hexBinary" use="optional" />
+ <xsd:attribute name="float" type="xsd:float" use="optional" />
+ <xsd:attribute name="decimal" use="optional">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:decimal">
+ <xsd:fractionDigits value="0"></xsd:fractionDigits>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ <xsd:attribute name="double" type="xsd:double" use="optional" />
+ <xsd:attribute name="anyURI" type="xsd:anyURI" use="optional" />
+ <xsd:attribute name="qname" type="xsd:QName" use="optional" />
+ <xsd:attribute name="normalizedString" type="xsd:normalizedString" use="optional" />
+ <xsd:attribute name="token" type="xsd:token" use="optional" />
+ <xsd:attribute name="language" type="xsd:language" use="optional" />
+ <xsd:attribute name="name" type="xsd:Name" use="optional" />
+ <xsd:attribute name="ncName" type="xsd:NCName" use="optional" />
+ <xsd:attribute name="nmtoken" type="xsd:NMTOKEN" use="optional" />
+ <xsd:attribute name="nmtokens" type="xsd:NMTOKENS" use="optional" />
+ <xsd:attribute name="id" type="xsd:ID" use="optional" />
+ <xsd:attribute name="idref" type="xsd:IDREF" use="optional" />
+ <xsd:attribute name="idrefs" type="xsd:IDREFS" use="optional" />
+ <xsd:attribute name="entity" type="xsd:ENTITY" use="optional" />
+ <xsd:attribute name="entities" type="xsd:ENTITIES" use="optional" />
+ <xsd:attribute name="integer" type="xsd:integer" use="optional" />
+ <xsd:attribute name="nonPositiveInteger" type="xsd:nonPositiveInteger" use="optional" />
+ <xsd:attribute name="nonNegativeInteger" type="xsd:nonNegativeInteger" use="optional" />
+ <xsd:attribute name="positiveInteger" type="xsd:positiveInteger" use="optional" />
+ <xsd:attribute name="negativeInteger" type="xsd:negativeInteger" use="optional" />
+ <xsd:attribute name="long" type="xsd:long" use="optional" />
+ <xsd:attribute name="int" type="xsd:int" use="optional" />
+ <xsd:attribute name="short" type="xsd:short" use="optional" />
+ <xsd:attribute name="byte" type="xsd:byte" use="optional" />
+ <xsd:attribute name="unsignedLong" type="xsd:unsignedLong" use="optional" />
+ <xsd:attribute name="unsignedInt" type="xsd:unsignedInt" use="optional" />
+ <xsd:attribute name="unsignedShort" type="xsd:unsignedShort" use="optional" />
+ <xsd:attribute name="unsignedByte" type="xsd:unsignedByte" use="optional" />
+ <xsd:attribute name="unknown" use="optional"/>
+ </xsd:attributeGroup>
+
+ <xsd:group name="groupOfAll">
+ <xsd:annotation>
+ <xsd:documentation>An All Group</xsd:documentation>
+ </xsd:annotation>
+ <xsd:all>
+ <xsd:element ref="avro:primitive" />
+ <xsd:element ref="avro:nonNullPrimitive" />
+ <xsd:element ref="avro:record" />
+ <xsd:element ref="avro:list" />
+ </xsd:all>
+ </xsd:group>
+
+ <xsd:simpleType name="nonNullPrimitiveType">
+ <xsd:restriction base="avro:primitiveType">
+ <xsd:enumeration value="boolean" />
+ <xsd:enumeration value="int" />
+ <xsd:enumeration value="long" />
+ <xsd:enumeration value="float" />
+ <xsd:enumeration value="double" />
+ <xsd:enumeration value="decimal" />
+ <xsd:enumeration value="bytes" />
+ <xsd:enumeration value="string" />
+ </xsd:restriction>
+ </xsd:simpleType>
+</xsd:schema>
diff --git a/xmlschema-walker/src/test/resources/test_mfpn2_included2.xsd b/xmlschema-walker/src/test/resources/test_mfpn2_included2.xsd
new file mode 100644
index 0000000..5d726ac
--- /dev/null
+++ b/xmlschema-walker/src/test/resources/test_mfpn2_included2.xsd
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+ <!--
+ This file is included by test_multiple_files_per_namespace2.xsd
+ -->
+ <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://avro.apache.org/AvroTest" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:avro="http://avro.apache.org/AvroTest">
+
+ <xsd:attribute name="size">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:nonNegativeInteger">
+ <xsd:maxExclusive value="100" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+ <xsd:group name="group">
+ <xsd:annotation>
+ <xsd:documentation>A group of nested sequences, choices, and elements.</xsd:documentation>
+ </xsd:annotation>
+ <xsd:sequence>
+ <xsd:choice minOccurs="0" maxOccurs="unbounded">
+ <xsd:element ref="avro:primitive" />
+ <xsd:element ref="avro:nonNullPrimitive" />
+ <xsd:element ref="avro:record" />
+ <xsd:element ref="avro:list" />
+ <xsd:element ref="avro:tuple" />
+ </xsd:choice>
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:complexType name="recordType">
+ <xsd:group ref="avro:group" />
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/xmlschema-walker/src/test/resources/test_mfpn_included1.xsd b/xmlschema-walker/src/test/resources/test_mfpn_included1.xsd
new file mode 100644
index 0000000..cad2370
--- /dev/null
+++ b/xmlschema-walker/src/test/resources/test_mfpn_included1.xsd
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+ <!--
+ This file is included by test_multiple_files_per_namespace.xsd
+ -->
+<xs:schema targetNamespace="http://avro.apache.org/AvroTest"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:avro="http://avro.apache.org/AvroTest"
+ xmlns:avro2="http://avro.apache.org/AvroTest2">
+
+ <xs:import namespace="http://avro.apache.org/AvroTest2" schemaLocation="test_mfpn_included2.xsd"/>
+ <xs:import namespace="" schemaLocation="test_mfpn_included3.xsd"/>
+
+ <xs:complexType name="Included">
+ <xs:sequence>
+ <xs:element name="includedElement" type="xs:string"/>
+ <xs:element name="differentNamespaceType" type="avro2:DifferentNS"/>
+ <xs:element name="noNamespaceType" type="NoNS"/>
+ </xs:sequence>
+ </xs:complexType>
+
+</xs:schema>
diff --git a/xmlschema-walker/src/test/resources/test_mfpn_included2.xsd b/xmlschema-walker/src/test/resources/test_mfpn_included2.xsd
new file mode 100644
index 0000000..11f26ff
--- /dev/null
+++ b/xmlschema-walker/src/test/resources/test_mfpn_included2.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+ <!--
+ This file is imported by test_mpfn_included1 which is in turn included by test_multiple_files_per_namespace.xsd
+ -->
+<xs:schema targetNamespace="http://avro.apache.org/AvroTest2"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:avro2="http://avro.apache.org/AvroTest2">
+
+ <xs:complexType name="DifferentNS">
+ <xs:sequence>
+ <xs:element name="differentNamespaceElement" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+
+</xs:schema>
diff --git a/xmlschema-walker/src/test/resources/test_mfpn_included3.xsd b/xmlschema-walker/src/test/resources/test_mfpn_included3.xsd
new file mode 100644
index 0000000..0a98076
--- /dev/null
+++ b/xmlschema-walker/src/test/resources/test_mfpn_included3.xsd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+ <!--
+ This file is imported by test_mpfn_included1 which is in turn included by test_multiple_files_per_namespace.xsd
+ -->
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:complexType name="NoNS">
+ <xs:sequence>
+ <xs:element name="noNSElement" type="xs:string"/>
+ </xs:sequence>
+ </xs:complexType>
+
+</xs:schema>
diff --git a/xmlschema-walker/src/test/resources/test_multiple_files_per_namespace.xsd b/xmlschema-walker/src/test/resources/test_multiple_files_per_namespace.xsd
new file mode 100644
index 0000000..7ba23c9
--- /dev/null
+++ b/xmlschema-walker/src/test/resources/test_multiple_files_per_namespace.xsd
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+<xs:schema targetNamespace="http://avro.apache.org/AvroTest"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema"
+ xmlns:avro="http://avro.apache.org/AvroTest">
+
+ <xs:include schemaLocation="test_mfpn_included1.xsd"/>
+
+ <xs:complexType name="BaseType">
+ <xs:sequence>
+ <xs:element name="baseElement" type="xs:string"/>
+ <xs:element name="includedType" type="avro:Included"/>
+ </xs:sequence>
+ </xs:complexType>
+
+ <xs:complexType name="Test">
+ <xs:complexContent>
+ <xs:extension base="avro:BaseType"/>
+ </xs:complexContent>
+ </xs:complexType>
+
+ <xs:element name="root" type="avro:Test"/>
+</xs:schema>
diff --git a/xmlschema-walker/src/test/resources/test_multiple_files_per_namespace2.xsd b/xmlschema-walker/src/test/resources/test_multiple_files_per_namespace2.xsd
new file mode 100644
index 0000000..5cc2bef
--- /dev/null
+++ b/xmlschema-walker/src/test/resources/test_multiple_files_per_namespace2.xsd
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+ -->
+
+ <!--
+ This test distributes test_schema.xsd among three files, this one, test_mfpn2_included1.xsd
+ and test_mfpn2_included2.xsd
+ -->
+<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://avro.apache.org/AvroTest" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:avro="http://avro.apache.org/AvroTest">
+ <xsd:include schemaLocation="test_mfpn2_included1.xsd"/>
+ <xsd:include schemaLocation="test_mfpn2_included2.xsd"/>
+
+ <xsd:attribute name="id">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:ID">
+ <xsd:minLength value="1" />
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+
+ <xsd:simpleType name="primitiveType">
+ <xsd:restriction base="xsd:NMTOKEN">
+ <xsd:enumeration value="null" />
+ <xsd:enumeration value="boolean" />
+ <xsd:enumeration value="int" />
+ <xsd:enumeration value="long" />
+ <xsd:enumeration value="float" />
+ <xsd:enumeration value="double" />
+ <xsd:enumeration value="decimal" />
+ <xsd:enumeration value="bytes" />
+ <xsd:enumeration value="string" />
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:element name="root">
+ <xsd:complexType>
+ <xsd:group ref="avro:group" />
+ <xsd:attributeGroup ref="avro:attrGroup" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="primitive" type="avro:primitiveType" />
+ <xsd:element name="nonNullPrimitive" type="avro:nonNullPrimitiveType" />
+
+ <xsd:element name="record" type="avro:recordType" />
+ <xsd:element name="map" substitutionGroup="avro:record">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="avro:recordType">
+ <xsd:attribute ref="avro:id" use="required" />
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="list">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element ref="avro:primitive" minOccurs="1" maxOccurs="100" />
+ <xsd:element ref="avro:record" minOccurs="1" maxOccurs="100" />
+ </xsd:choice>
+ <xsd:attribute ref="avro:size" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="tuple">
+ <xsd:complexType>
+ <xsd:group ref="avro:groupOfAll" />
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="nonNullRecord">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:restriction base="avro:recordType">
+ <xsd:sequence>
+ <xsd:element ref="avro:nonNullPrimitive" />
+ </xsd:sequence>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+</xsd:schema>