import static com.google.common.base.Preconditions.checkNotNull;
+import com.google.common.base.Preconditions;
+import com.google.gson.stream.JsonWriter;
import java.io.IOException;
import java.net.URI;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
-
import javax.activation.UnsupportedDataTypeException;
-
import org.opendaylight.controller.sal.core.api.mount.MountInstance;
import org.opendaylight.controller.sal.restconf.impl.ControllerContext;
import org.opendaylight.controller.sal.restconf.impl.IdentityValuesDTO;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
import org.opendaylight.yangtools.yang.data.api.Node;
import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import com.google.common.base.Preconditions;
-import com.google.gson.stream.JsonWriter;
-
class JsonMapper {
- private final Set<LeafListSchemaNode> foundLeafLists = new HashSet<>();
- private final Set<ListSchemaNode> foundLists = new HashSet<>();
private MountInstance mountPoint;
private final Logger logger = LoggerFactory.getLogger(JsonMapper.class);
}
writer.endObject();
-
- foundLeafLists.clear();
- foundLists.clear();
}
private void writeChildrenOfParent(final JsonWriter writer, final CompositeNode parent, final DataNodeContainer parentSchema)
throws IOException {
checkNotNull(parent);
+ final Set<QName> foundLists = new HashSet<>();
+
Set<DataSchemaNode> parentSchemaChildNodes = parentSchema == null ?
Collections.<DataSchemaNode>emptySet() : parentSchema.getChildNodes();
logger.debug( "No schema found for data node \"" + child.getNodeType() );
- handleNoSchemaFound( writer, child, parent );
+ if( !foundLists.contains( child.getNodeType() ) ) {
+ handleNoSchemaFound( writer, child, parent );
+
+ // Since we don't have a schema, we don't know which nodes are supposed to be
+ // lists so treat every one as a potential list to avoid outputting duplicates.
+
+ foundLists.add( child.getNodeType() );
+ }
}
else if (childSchema instanceof ContainerSchemaNode) {
Preconditions.checkState(child instanceof CompositeNode,
"Data representation of Container should be CompositeNode - " + child.getNodeType());
writeContainer(writer, (CompositeNode) child, (ContainerSchemaNode) childSchema);
} else if (childSchema instanceof ListSchemaNode) {
- if (!foundLists.contains(childSchema)) {
+ if (!foundLists.contains( child.getNodeType() ) ) {
Preconditions.checkState(child instanceof CompositeNode,
"Data representation of List should be CompositeNode - " + child.getNodeType());
- foundLists.add((ListSchemaNode) childSchema);
+ foundLists.add( child.getNodeType() );
writeList(writer, parent, (CompositeNode) child, (ListSchemaNode) childSchema);
}
} else if (childSchema instanceof LeafListSchemaNode) {
- if (!foundLeafLists.contains(childSchema)) {
+ if (!foundLists.contains( child.getNodeType() ) ) {
Preconditions.checkState(child instanceof SimpleNode<?>,
"Data representation of LeafList should be SimpleNode - " + child.getNodeType());
- foundLeafLists.add((LeafListSchemaNode) childSchema);
+ foundLists.add( child.getNodeType() );
writeLeafList(writer, parent, (SimpleNode<?>) child, (LeafListSchemaNode) childSchema);
}
} else if (childSchema instanceof LeafSchemaNode) {
Preconditions.checkState(child instanceof SimpleNode<?>,
"Data representation of LeafList should be SimpleNode - " + child.getNodeType());
writeLeaf(writer, (SimpleNode<?>) child, (LeafSchemaNode) childSchema);
+ } else if (childSchema instanceof AnyXmlSchemaNode) {
+ if( child instanceof CompositeNode ) {
+ writeContainer(writer, (CompositeNode) child, null);
+ }
+ else {
+ handleNoSchemaFound( writer, child, parent );
+ }
} else {
throw new UnsupportedDataTypeException("Schema can be ContainerSchemaNode, ListSchemaNode, "
+ "LeafListSchemaNode, or LeafSchemaNode. Other types are not supported yet.");
}
}
+ }
- for (Node<?> child : parent.getValue()) {
- DataSchemaNode childSchema = findFirstSchemaForNode(child, parentSchemaChildNodes);
- if (childSchema instanceof LeafListSchemaNode) {
- foundLeafLists.remove(childSchema);
- } else if (childSchema instanceof ListSchemaNode) {
- foundLists.remove(childSchema);
- }
+ private void writeValue( final JsonWriter writer, Object value ) throws IOException {
+ if( value != null ) {
+ writer.value( String.valueOf( value ) );
+ }
+ else {
+ writer.value( "" );
}
}
private void handleNoSchemaFound( final JsonWriter writer, final Node<?> node,
final CompositeNode parent ) throws IOException {
if( node instanceof SimpleNode<?> ) {
- writeName( node, null, writer );
- Object value = node.getValue();
- if( value != null ) {
- writer.value( String.valueOf( value ) );
+ List<SimpleNode<?>> nodeLeafList = parent.getSimpleNodesByName( node.getNodeType() );
+ if( nodeLeafList.size() == 1 ) {
+ writeName( node, null, writer );
+ writeValue( writer, node.getValue() );
+ }
+ else { // more than 1, write as a json array
+ writeName( node, null, writer );
+ writer.beginArray();
+ for( SimpleNode<?> leafNode: nodeLeafList ) {
+ writeValue( writer, leafNode.getValue() );
+ }
+
+ writer.endArray();
}
} else { // CompositeNode
Preconditions.checkState( node instanceof CompositeNode,
"Data representation of Container should be CompositeNode - " + node.getNodeType() );
- writeContainer( writer, (CompositeNode) node, null );
+ List<CompositeNode> nodeList = parent.getCompositesByName( node.getNodeType() );
+ if( nodeList.size() == 1 ) {
+ writeContainer( writer, (CompositeNode) node, null );
+ }
+ else { // more than 1, write as a json array
+ writeList( writer, parent, (CompositeNode) node, null );
+ }
}
}
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifier;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
public boolean isInstantiatedDataSchema( final DataSchemaNode node ) {
return node instanceof LeafSchemaNode || node instanceof LeafListSchemaNode ||
- node instanceof ContainerSchemaNode || node instanceof ListSchemaNode;
+ node instanceof ContainerSchemaNode || node instanceof ListSchemaNode ||
+ node instanceof AnyXmlSchemaNode;
}
private void addKeyValue( final HashMap<QName, Object> map, final DataSchemaNode node,
import org.opendaylight.yangtools.yang.data.api.SimpleNode;
import org.opendaylight.yangtools.yang.data.impl.ImmutableCompositeNode;
import org.opendaylight.yangtools.yang.data.impl.NodeFactory;
+import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
}
}
- if ((nodeBuilder instanceof CompositeNodeWrapper)) {
- final List<NodeWrapper<?>> children = ((CompositeNodeWrapper) nodeBuilder).getValues();
- for (final NodeWrapper<? extends Object> child : children) {
- final List<DataSchemaNode> potentialSchemaNodes =
- this.controllerContext.findInstanceDataChildrenByName(
- ((DataNodeContainer) schema), child.getLocalName());
+ if ( nodeBuilder instanceof CompositeNodeWrapper ) {
+ if( schema instanceof DataNodeContainer ) {
+ normalizeCompositeNode( (CompositeNodeWrapper)nodeBuilder, (DataNodeContainer)schema,
+ mountPoint, currentAugment );
+ }
+ else if( schema instanceof AnyXmlSchemaNode ) {
+ normalizeAnyXmlNode( (CompositeNodeWrapper)nodeBuilder, (AnyXmlSchemaNode)schema );
+ }
+ }
+ else if ( nodeBuilder instanceof SimpleNodeWrapper ) {
+ normalizeSimpleNode( (SimpleNodeWrapper) nodeBuilder, schema, mountPoint );
+ }
+ else if ((nodeBuilder instanceof EmptyNodeWrapper)) {
+ normalizeEmptyNode( (EmptyNodeWrapper) nodeBuilder, schema );
+ }
+ }
- if (potentialSchemaNodes.size() > 1 && child.getNamespace() == null) {
- StringBuilder builder = new StringBuilder();
- for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
- builder.append(" ").append(potentialSchemaNode.getQName().getNamespace().toString())
- .append("\n");
- }
+ private void normalizeAnyXmlNode( CompositeNodeWrapper compositeNode, AnyXmlSchemaNode schema ) {
+ List<NodeWrapper<?>> children = compositeNode.getValues();
+ for( NodeWrapper<? extends Object> child : children ) {
+ child.setNamespace( schema.getQName().getNamespace() );
+ if( child instanceof CompositeNodeWrapper ) {
+ normalizeAnyXmlNode( (CompositeNodeWrapper)child, schema );
+ }
+ }
+ }
- throw new RestconfDocumentedException(
- "Node \"" + child.getLocalName() +
- "\" is added as augment from more than one module. " +
- "Therefore node must have namespace (XML format) or module name (JSON format)." +
- "\nThe node is added as augment from modules with namespaces:\n" + builder,
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
- }
+ private void normalizeEmptyNode( EmptyNodeWrapper emptyNodeBuilder, DataSchemaNode schema ) {
+ if ((schema instanceof LeafSchemaNode)) {
+ emptyNodeBuilder.setComposite(false);
+ }
+ else {
+ if ((schema instanceof ContainerSchemaNode)) {
+ // FIXME: Add presence check
+ emptyNodeBuilder.setComposite(true);
+ }
+ }
+ }
+
+ private void normalizeSimpleNode( SimpleNodeWrapper simpleNode, DataSchemaNode schema,
+ MountInstance mountPoint ) {
+ final Object value = simpleNode.getValue();
+ Object inputValue = value;
+ TypeDefinition<? extends Object> typeDefinition = this.typeDefinition(schema);
+ if ((typeDefinition instanceof IdentityrefTypeDefinition)) {
+ if ((value instanceof String)) {
+ inputValue = new IdentityValuesDTO( simpleNode.getNamespace().toString(),
+ (String) value, null, (String) value );
+ } // else value is already instance of IdentityValuesDTO
+ }
+
+ Object outputValue = inputValue;
+
+ if( typeDefinition != null ) {
+ Codec<Object,Object> codec = RestCodec.from(typeDefinition, mountPoint);
+ outputValue = codec == null ? null : codec.deserialize(inputValue);
+ }
+
+ simpleNode.setValue(outputValue);
+ }
- boolean rightNodeSchemaFound = false;
+ private void normalizeCompositeNode( CompositeNodeWrapper compositeNodeBuilder,
+ DataNodeContainer schema, MountInstance mountPoint,
+ QName currentAugment ) {
+ final List<NodeWrapper<?>> children = compositeNodeBuilder.getValues();
+ for (final NodeWrapper<? extends Object> child : children) {
+ final List<DataSchemaNode> potentialSchemaNodes =
+ this.controllerContext.findInstanceDataChildrenByName(
+ schema, child.getLocalName());
+
+ if (potentialSchemaNodes.size() > 1 && child.getNamespace() == null) {
+ StringBuilder builder = new StringBuilder();
for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
- if (!rightNodeSchemaFound) {
- final QName potentialCurrentAugment =
- this.normalizeNodeName(child, potentialSchemaNode, currentAugment, mountPoint);
- if (child.getQname() != null ) {
- this.normalizeNode(child, potentialSchemaNode, potentialCurrentAugment, mountPoint);
- rightNodeSchemaFound = true;
- }
- }
+ builder.append(" ").append(potentialSchemaNode.getQName().getNamespace().toString())
+ .append("\n");
}
- if (!rightNodeSchemaFound) {
- throw new RestconfDocumentedException(
- "Schema node \"" + child.getLocalName() + "\" was not found in module.",
- ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT );
- }
+ throw new RestconfDocumentedException(
+ "Node \"" + child.getLocalName() +
+ "\" is added as augment from more than one module. " +
+ "Therefore node must have namespace (XML format) or module name (JSON format)." +
+ "\nThe node is added as augment from modules with namespaces:\n" + builder,
+ ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
}
- if ((schema instanceof ListSchemaNode)) {
- final List<QName> listKeys = ((ListSchemaNode) schema).getKeyDefinition();
- for (final QName listKey : listKeys) {
- boolean foundKey = false;
- for (final NodeWrapper<? extends Object> child : children) {
- if (Objects.equal(child.unwrap().getNodeType().getLocalName(), listKey.getLocalName())) {
- foundKey = true;
- }
- }
-
- if (!foundKey) {
- throw new RestconfDocumentedException(
- "Missing key in URI \"" + listKey.getLocalName() +
- "\" of list \"" + schema.getQName().getLocalName() + "\"",
- ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+ boolean rightNodeSchemaFound = false;
+ for (final DataSchemaNode potentialSchemaNode : potentialSchemaNodes) {
+ if (!rightNodeSchemaFound) {
+ final QName potentialCurrentAugment =
+ this.normalizeNodeName(child, potentialSchemaNode, currentAugment, mountPoint);
+ if (child.getQname() != null ) {
+ this.normalizeNode(child, potentialSchemaNode, potentialCurrentAugment, mountPoint);
+ rightNodeSchemaFound = true;
}
}
}
- }
- else {
- if ((nodeBuilder instanceof SimpleNodeWrapper)) {
- final SimpleNodeWrapper simpleNode = ((SimpleNodeWrapper) nodeBuilder);
- final Object value = simpleNode.getValue();
- Object inputValue = value;
- TypeDefinition<? extends Object> typeDefinition = this.typeDefinition(schema);
- if ((typeDefinition instanceof IdentityrefTypeDefinition)) {
- if ((value instanceof String)) {
- inputValue = new IdentityValuesDTO( nodeBuilder.getNamespace().toString(),
- (String) value, null, (String) value );
- } // else value is already instance of IdentityValuesDTO
- }
- Codec<Object,Object> codec = RestCodec.from(typeDefinition, mountPoint);
- Object outputValue = codec == null ? null : codec.deserialize(inputValue);
-
- simpleNode.setValue(outputValue);
+ if (!rightNodeSchemaFound) {
+ throw new RestconfDocumentedException(
+ "Schema node \"" + child.getLocalName() + "\" was not found in module.",
+ ErrorType.APPLICATION, ErrorTag.UNKNOWN_ELEMENT );
}
- else {
- if ((nodeBuilder instanceof EmptyNodeWrapper)) {
- final EmptyNodeWrapper emptyNodeBuilder = ((EmptyNodeWrapper) nodeBuilder);
- if ((schema instanceof LeafSchemaNode)) {
- emptyNodeBuilder.setComposite(false);
- }
- else {
- if ((schema instanceof ContainerSchemaNode)) {
- // FIXME: Add presence check
- emptyNodeBuilder.setComposite(true);
- }
+ }
+
+ if ((schema instanceof ListSchemaNode)) {
+ ListSchemaNode listSchemaNode = (ListSchemaNode)schema;
+ final List<QName> listKeys = listSchemaNode.getKeyDefinition();
+ for (final QName listKey : listKeys) {
+ boolean foundKey = false;
+ for (final NodeWrapper<? extends Object> child : children) {
+ if (Objects.equal(child.unwrap().getNodeType().getLocalName(), listKey.getLocalName())) {
+ foundKey = true;
}
}
+
+ if (!foundKey) {
+ throw new RestconfDocumentedException(
+ "Missing key in URI \"" + listKey.getLocalName() +
+ "\" of list \"" + listSchemaNode.getQName().getLocalName() + "\"",
+ ErrorType.PROTOCOL, ErrorTag.INVALID_VALUE );
+ }
}
}
}
else if (node instanceof LeafSchemaNode) {
return _typeDefinition((LeafSchemaNode)node);
}
+ else if (node instanceof AnyXmlSchemaNode) {
+ return null;
+ }
else {
throw new IllegalArgumentException("Unhandled parameter types: " +
Arrays.<Object>asList(node).toString());
}
+ static class ComplexAnyXmlVerifier extends LeafVerifier {
+
+ ComplexAnyXmlVerifier() {
+ super( null, JsonToken.BEGIN_OBJECT );
+ }
+
+ @Override
+ void verify( JsonReader reader, String keyName ) throws IOException {
+
+ reader.beginObject();
+ String innerKey = reader.nextName();
+ assertEquals( "Json reader child key for " + keyName, "data", innerKey );
+ assertEquals( "Json token type for key " + innerKey, JsonToken.BEGIN_OBJECT, reader.peek() );
+
+ reader.beginObject();
+ verifyLeaf( reader, innerKey, "leaf1", "leaf1-value" );
+ verifyLeaf( reader, innerKey, "leaf2", "leaf2-value" );
+
+ String nextName = reader.nextName();
+ assertEquals( "Json reader child key for " + innerKey, "leaf-list", nextName );
+ reader.beginArray();
+ assertEquals( "Json value for key " + nextName, "leaf-list-value1", reader.nextString() );
+ assertEquals( "Json value for key " + nextName, "leaf-list-value2", reader.nextString() );
+ reader.endArray();
+
+ nextName = reader.nextName();
+ assertEquals( "Json reader child key for " + innerKey, "list", nextName );
+ reader.beginArray();
+ verifyNestedLists( reader, 1 );
+ verifyNestedLists( reader, 3 );
+ reader.endArray();
+
+ reader.endObject();
+ reader.endObject();
+ }
+
+ void verifyNestedLists( JsonReader reader, int leafNum ) throws IOException {
+ reader.beginObject();
+
+ String nextName = reader.nextName();
+ assertEquals( "Json reader next name", "nested-list", nextName );
+
+ reader.beginArray();
+
+ reader.beginObject();
+ verifyLeaf( reader, "nested-list", "nested-leaf", "nested-value" + leafNum++ );
+ reader.endObject();
+
+ reader.beginObject();
+ verifyLeaf( reader, "nested-list", "nested-leaf", "nested-value" + leafNum );
+ reader.endObject();
+
+ reader.endArray();
+ reader.endObject();
+ }
+
+ void verifyLeaf( JsonReader reader, String parent, String name, String value ) throws IOException {
+ String nextName = reader.nextName();
+ assertEquals( "Json reader child key for " + parent, name, nextName );
+ assertEquals( "Json token type for key " + parent, JsonToken.STRING, reader.peek() );
+ assertEquals( "Json value for key " + nextName, value, reader.nextString() );
+ }
+
+ @Override
+ Object getActualValue( JsonReader reader ) throws IOException {
+ return null;
+ }
+ }
+
@BeforeClass
public static void initialize() {
dataLoad("/cnsn-to-json/simple-data-types");
expectedMap.put( "lfunion14", new StringVerifier( "zero" ) );
expectedMap.put( "lfempty", new EmptyVerifier() );
expectedMap.put( "identityref1", new StringVerifier( "simple-data-types:iden" ) );
+ expectedMap.put( "complex-any", new ComplexAnyXmlVerifier() );
+ expectedMap.put( "simple-any", new StringVerifier( "simple" ) );
+ expectedMap.put( "empty-any", new StringVerifier( "" ) );
while (jReader.hasNext()) {
String keyName = jReader.nextName();
package org.opendaylight.controller.sal.restconf.impl.test;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.when;
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Maps;
+import com.google.common.io.ByteStreams;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonParser;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
-
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import javax.ws.rs.core.Application;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;
-
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.test.JerseyTest;
import org.junit.Before;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
-import com.google.common.collect.ImmutableMap;
-import com.google.common.collect.Maps;
-import com.google.common.io.ByteStreams;
-import com.google.gson.JsonArray;
-import com.google.gson.JsonElement;
-import com.google.gson.JsonParser;
-
/**
* Unit tests for RestconfDocumentedExceptionMapper.
*
errorListEntrySet.iterator().next().getKey() );
assertTrue( "\"error\" Json element is not an Array", errorListElement.isJsonArray() );
+ // As a final check, make sure there aren't multiple "error" array elements. Unfortunately,
+ // the call above to getAsJsonObject().entrySet() will out duplicate "error" elements. So
+ // we'll use regex on the json string to verify this.
+
+ Matcher matcher = Pattern.compile( "\"error\"[ ]*:[ ]*\\[", Pattern.DOTALL ).matcher( bos.toString() );
+ assertTrue( "Expected 1 \"error\" element", matcher.find() );
+ assertFalse( "Found multiple \"error\" elements", matcher.find() );
+
return errorListElement.getAsJsonArray();
}
final ErrorInfoVerifier errorInfoVerifier ) {
JsonElement errorInfoElement = null;
- Map<String, String> actualErrorInfo = null;
Map<String, String> leafMap = Maps.newHashMap();
for( Entry<String, JsonElement> entry: errorEntryElement.getAsJsonObject().entrySet() ) {
String leafName = entry.getKey();
*/
package org.opendaylight.controller.sal.restconf.impl.test.structures;
+import static org.junit.Assert.assertFalse;
import java.util.HashMap;
import java.util.Map;
}
public void addLfLst(LfLst lfLst) {
+ assertFalse( "Found multiple leaf list elements for " + lfLst.getName(),
+ lfLsts.containsKey( lfLst.getName() ) );
lfLsts.put(lfLst.getName(), lfLst);
}
public void addLst(Lst lst) {
+ assertFalse( "Found multiple list elements for " + lst.getName(),
+ lsts.containsKey( lst.getName() ) );
lsts.put(lst.getName(), lst);
}
}
}
-
+ anyxml complex-any;
+
+ anyxml simple-any;
+
+ anyxml empty-any;
}
}
\ No newline at end of file
<lfenum>enum3</lfenum>
<lfbits>bit3 bit2</lfbits>
<lfbinary>ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz</lfbinary>
- <lfempty />
<lfunion1>324</lfunion1>
<lfunion2>33.3</lfunion2>
<lfunion3>55</lfunion3>
<lfunion12>false</lfunion12>
<lfunion13>b1</lfunion13>
<lfunion14>zero</lfunion14>
+ <lfempty />
<identityref1 xmlns:x="simple:data:types">x:iden</identityref1>
-</cont>
\ No newline at end of file
+ <complex-any>
+ <data>
+ <leaf1>leaf1-value</leaf1>
+ <leaf2>leaf2-value</leaf2>
+
+ <leaf-list>leaf-list-value1</leaf-list>
+ <leaf-list>leaf-list-value2</leaf-list>
+
+ <list>
+ <nested-list>
+ <nested-leaf>nested-value1</nested-leaf>
+ </nested-list>
+ <nested-list>
+ <nested-leaf>nested-value2</nested-leaf>
+ </nested-list>
+ </list>
+
+ <list>
+ <nested-list>
+ <nested-leaf>nested-value3</nested-leaf>
+ </nested-list>
+ <nested-list>
+ <nested-leaf>nested-value4</nested-leaf>
+ </nested-list>
+ </list>
+ </data>
+ </complex-any>
+ <simple-any>simple</simple-any>
+ <empty-any></empty-any>
+</cont>