import com.google.common.base.Strings;
import com.google.common.primitives.UnsignedInteger;
import java.net.URI;
+import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import javax.annotation.Nullable;
import javax.annotation.concurrent.NotThreadSafe;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.YangVersion;
+import org.opendaylight.yangtools.yang.model.api.ActionDefinition;
+import org.opendaylight.yangtools.yang.model.api.AnyDataSchemaNode;
import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
import org.opendaylight.yangtools.yang.model.api.ModuleImport;
import org.opendaylight.yangtools.yang.model.api.MustDefinition;
import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
+import org.opendaylight.yangtools.yang.model.api.OperationDefinition;
import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.Status;
import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.UniqueConstraint;
import org.opendaylight.yangtools.yang.model.api.UnknownSchemaNode;
import org.opendaylight.yangtools.yang.model.api.UsesNode;
import org.opendaylight.yangtools.yang.model.api.meta.EffectiveStatement;
import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.LeafrefTypeDefinition;
import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.ModifierKind;
import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition;
@NotThreadSafe
class SchemaContextEmitter {
- private final Rfc6020ModuleWriter writer;
+ private final YangModuleWriter writer;
private final boolean emitInstantiated;
private final boolean emitUses;
private final Map<QName, StatementDefinition> extensions;
+ private final YangVersion yangVersion;
- SchemaContextEmitter(final Rfc6020ModuleWriter writer, final Map<QName, StatementDefinition> extensions) {
- this(writer, extensions,false, true);
+ SchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
+ final YangVersion yangVersion) {
+ this(writer, extensions, yangVersion, false, true);
}
- SchemaContextEmitter(final Rfc6020ModuleWriter writer, final Map<QName, StatementDefinition> extensions, final boolean emitInstantiated, final boolean emitUses) {
+ SchemaContextEmitter(final YangModuleWriter writer, final Map<QName, StatementDefinition> extensions,
+ final YangVersion yangVersion, final boolean emitInstantiated, final boolean emitUses) {
this.writer = Preconditions.checkNotNull(writer);
this.emitInstantiated = emitInstantiated;
this.emitUses = emitUses;
this.extensions = Preconditions.checkNotNull(extensions);
+ this.yangVersion = yangVersion;
}
- static void writeToStatementWriter(final Module module, final SchemaContext ctx, final StatementTextWriter statementWriter) {
- final Rfc6020ModuleWriter yangSchemaWriter = SchemaToStatementWriterAdaptor.from(statementWriter);
+ static void writeToStatementWriter(final Module module, final SchemaContext ctx,
+ final StatementTextWriter statementWriter) {
+ final YangModuleWriter yangSchemaWriter = SchemaToStatementWriterAdaptor.from(statementWriter);
final Map<QName, StatementDefinition> extensions = ExtensionStatement.mapFrom(ctx.getExtensions());
- new SchemaContextEmitter(yangSchemaWriter,extensions).emitModule(module);
+ new SchemaContextEmitter(yangSchemaWriter, extensions, YangVersion.parse(module.getYangVersion()).orElse(null)).emitModule(module);
}
void emitModule(final Module input) {
}
private void emitMetaNodes(final Module input) {
-
- emitOrganizationNode(input.getOrganization()); // FIXME: BUG-2444: Optional
- emitContact(input.getContact()); // FIXME: BUG-2444: Optional
+ emitOrganizationNode(input.getOrganization());
+ emitContact(input.getContact());
emitDescriptionNode(input.getDescription());
emitReferenceNode(input.getReference());
}
for (final IdentitySchemaNode identity : input.getIdentities()) {
emitIdentity(identity);
}
+ for (final Deviation deviation : input.getDeviations()) {
+ emitDeviation(deviation);
+ }
emitDataNodeContainer(input);
for (final RpcDefinition rpc : input.getRpcs()) {
emitRpc(rpc);
}
- for (final NotificationDefinition notification : input.getNotifications()) {
- emitNotificationNode(notification);
- }
- for (final Deviation deviation : input.getDeviations()) {
- emitDeviation(deviation);
- }
+ emitNotifications(input.getNotifications());
}
private void emitDataNodeContainer(final DataNodeContainer input) {
emitChoice((ChoiceSchemaNode) child);
} else if (child instanceof AnyXmlSchemaNode) {
emitAnyxml((AnyXmlSchemaNode) child);
+ } else if (child instanceof AnyDataSchemaNode) {
+ emitAnydata((AnyDataSchemaNode) child);
} else {
throw new UnsupportedOperationException("Not supported DataSchemaNode type " + child.getClass());
}
private void emitImport(final ModuleImport importNode) {
writer.startImportNode(importNode.getModuleName());
+ emitDescriptionNode(importNode.getDescription());
+ emitReferenceNode(importNode.getReference());
emitPrefixNode(importNode.getPrefix());
emitRevisionDateNode(importNode.getRevision());
writer.endNode();
}
private void emitOrganizationNode(final String input) {
- writer.startOrganizationNode(input);
- writer.endNode();
-
+ if (!Strings.isNullOrEmpty(input)) {
+ writer.startOrganizationNode(input);
+ writer.endNode();
+ }
}
private void emitContact(final String input) {
- writer.startContactNode(input);
- writer.endNode();
-
+ if (!Strings.isNullOrEmpty(input)) {
+ writer.startContactNode(input);
+ writer.endNode();
+ }
}
private void emitDescriptionNode(@Nullable final String input) {
private void emitIdentity(final IdentitySchemaNode identity) {
writer.startIdentityNode(identity.getQName());
- if (identity.getBaseIdentity() != null) {
- emitBase(identity.getBaseIdentity().getQName());
- }
+ emitBaseIdentities(identity.getBaseIdentities());
emitStatusNode(identity.getStatus());
emitDescriptionNode(identity.getDescription());
emitReferenceNode(identity.getReference());
writer.endNode();
+ }
+ private void emitBaseIdentities(final Set<IdentitySchemaNode> identities) {
+ for (final IdentitySchemaNode identitySchemaNode : identities) {
+ emitBase(identitySchemaNode.getQName());
+ }
}
private void emitBase(final QName qName) {
writer.startBaseNode(qName);
writer.endNode();
-
}
private void emitFeature(final FeatureDefinition definition) {
} else if (typeDef instanceof UnionTypeDefinition) {
emitUnionSpecification((UnionTypeDefinition) typeDef);
} else if (typeDef instanceof BinaryTypeDefinition) {
- // FIXME: BUG-2444: Is this realy NOOP?
- // should at least support length statement
+ emitLength(((BinaryTypeDefinition) typeDef).getLengthConstraints());
} else if (typeDef instanceof BooleanTypeDefinition || typeDef instanceof EmptyTypeDefinition) {
// NOOP
} else {
// FIXME: BUG-2444: Optional
emitErrorAppTagNode(pattern.getErrorAppTag());
emitDescriptionNode(pattern.getDescription());
- // FIXME: BUG-2444: Optional
- emitReferenceNode(pattern.getReference());
+ emitModifier(pattern.getModifier());
writer.endNode();
}
+ private void emitModifier(final ModifierKind modifier) {
+ if(modifier != null) {
+ writer.startModifierNode(modifier);
+ writer.endNode();
+ }
+ }
+
+ private void emitDefaultNodes(final Collection<String> defaults) {
+ for (final String defaultValue : defaults) {
+ emitDefaultNode(defaultValue);
+ }
+ }
+
private void emitDefaultNode(@Nullable final Object object) {
if (object != null) {
writer.startDefaultNode(object.toString());
private void emitLeafrefSpecification(final LeafrefTypeDefinition typeDefinition) {
emitPathNode(typeDefinition.getPathStatement());
- // FIXME: BUG-2444: requireInstanceNode /Optional removed with (RFC6020 - Errata ID 2949)
- // Added in Yang 1.1
+ if (YangVersion.VERSION_1_1 == yangVersion) {
+ emitRequireInstanceNode(typeDefinition.requireInstance());
+ }
}
private void emitPathNode(final RevisionAwareXPath revisionAwareXPath) {
}
private void emitIdentityrefSpecification(final IdentityrefTypeDefinition typeDefinition) {
- emitBase(typeDefinition.getIdentity().getQName());
+ emitBaseIdentities(typeDefinition.getIdentities());
}
private void emitUnionSpecification(final UnionTypeDefinition typeDefinition) {
emitDocumentedNode(grouping);
emitDataNodeContainer(grouping);
emitUnknownStatementNodes(grouping.getUnknownSchemaNodes());
+ emitNotifications(grouping.getNotifications());
+ emitActions(grouping.getActions());
writer.endNode();
}
emitDocumentedNode(child);
emitDataNodeContainer(child);
emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+ emitNotifications(child.getNotifications());
+ emitActions(child.getActions());
writer.endNode();
}
for (final MustDefinition mustCondition : constraints.getMustConstraints()) {
emitMust(mustCondition);
}
-
}
private void emitLeaf(final LeafSchemaNode child) {
emitWhen(child.getConstraints().getWhenCondition());
// FIXME: BUG-2444: *(ifFeatureNode )
emitTypeNode(child.getPath(), child.getType());
+ emitUnitsNode(child.getType().getUnits());
// FIXME: BUG-2444: unitsNode /Optional
emitMustNodes(child.getConstraints().getMustConstraints());
emitConfigNode(child.isConfiguration());
-
+ emitDefaultNodes(child.getDefaults());
emitMinElementsNode(child.getConstraints().getMinElements());
emitMaxElementsNode(child.getConstraints().getMaxElements());
emitOrderedBy(child.isUserOrdered());
// FIXME: BUG-2444: *(ifFeatureNode )
emitMustNodes(child.getConstraints().getMustConstraints());
emitKey(child.getKeyDefinition());
- // FIXME: BUG-2444: *(uniqueNode )
+ emitUniqueConstraints(child.getUniqueConstraints());
emitConfigNode(child.isConfiguration());
emitMinElementsNode(child.getConstraints().getMinElements());
emitMaxElementsNode(child.getConstraints().getMaxElements());
emitDocumentedNode(child);
emitDataNodeContainer(child);
emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+ emitNotifications(child.getNotifications());
+ emitActions(child.getActions());
writer.endNode();
}
}
}
- @SuppressWarnings("unused")
- private void emitUnique(final String input) {
- // FIXME: BUG-2444: writer.startUniqueNode(uniqueArgStr)); Nodeend
+ private void emitUniqueConstraints(final Collection<UniqueConstraint> uniqueConstraints) {
+ for (final UniqueConstraint uniqueConstraint : uniqueConstraints) {
+ emitUnique(uniqueConstraint);
+ }
+ }
+ private void emitUnique(final UniqueConstraint uniqueConstraint) {
+ writer.startUniqueNode(uniqueConstraint);
+ writer.endNode();
}
private void emitChoice(final ChoiceSchemaNode choice) {
}
- private void emitAnyxml(final AnyXmlSchemaNode child) {
- writer.startAnyxmlNode(child.getQName());
+ private void emitAnyxml(final AnyXmlSchemaNode anyxml) {
+ writer.startAnyxmlNode(anyxml.getQName());
+ emitBodyOfDataSchemaNode(anyxml);
+ writer.endNode();
+ }
- emitWhen(child.getConstraints().getWhenCondition());
- // FIXME: BUG-2444: *(ifFeatureNode )
- emitMustNodes(child.getConstraints().getMustConstraints());
- emitConfigNode(child.isConfiguration());
- emitMandatoryNode(child.getConstraints().isMandatory());
- emitDocumentedNode(child);
- emitUnknownStatementNodes(child.getUnknownSchemaNodes());
+ private void emitAnydata(final AnyDataSchemaNode anydata) {
+ writer.startAnydataNode(anydata.getQName());
+ emitBodyOfDataSchemaNode(anydata);
writer.endNode();
+ }
+ private void emitBodyOfDataSchemaNode(final DataSchemaNode dataSchemaNode) {
+ emitWhen(dataSchemaNode.getConstraints().getWhenCondition());
+ // FIXME: BUG-2444: *(ifFeatureNode )
+ emitMustNodes(dataSchemaNode.getConstraints().getMustConstraints());
+ emitConfigNode(dataSchemaNode.isConfiguration());
+ emitMandatoryNode(dataSchemaNode.getConstraints().isMandatory());
+ emitDocumentedNode(dataSchemaNode);
+ emitUnknownStatementNodes(dataSchemaNode.getUnknownSchemaNodes());
}
private void emitUsesNode(final UsesNode usesNode) {
}
}
emitUnknownStatementNodes(augmentation.getUnknownSchemaNodes());
+ emitNotifications(augmentation.getNotifications());
+ emitActions(augmentation.getActions());
writer.endNode();
}
private void emitRpc(final RpcDefinition rpc) {
writer.startRpcNode(rpc.getQName());
+ emitOperationBody(rpc);
+ writer.endNode();
+ }
+
+ private void emitOperationBody(final OperationDefinition rpc) {
// FIXME: BUG-2444: *(ifFeatureNode )
emitStatusNode(rpc.getStatus());
emitDescriptionNode(rpc.getDescription());
emitInput(rpc.getInput());
emitOutput(rpc.getOutput());
emitUnknownStatementNodes(rpc.getUnknownSchemaNodes());
- writer.endNode();
+ }
+ private void emitActions(final Set<ActionDefinition> actions) {
+ for (final ActionDefinition actionDefinition : actions) {
+ emitAction(actionDefinition);
+ }
+ }
+
+ private void emitAction(final ActionDefinition action) {
+ writer.startActionNode(action.getQName());
+ emitOperationBody(action);
+ writer.endNode();
}
private void emitInput(@Nonnull final ContainerSchemaNode input) {
if (isExplicitStatement(input)) {
writer.startInputNode();
+ emitConstraints(input.getConstraints());
emitDataNodeContainer(input);
emitUnknownStatementNodes(input.getUnknownSchemaNodes());
writer.endNode();
private void emitOutput(@Nonnull final ContainerSchemaNode output) {
if (isExplicitStatement(output)) {
writer.startOutputNode();
+ emitConstraints(output.getConstraints());
emitDataNodeContainer(output);
emitUnknownStatementNodes(output.getUnknownSchemaNodes());
writer.endNode();
&& ((EffectiveStatement<?, ?>) node).getDeclared().getStatementSource() == StatementSource.DECLARATION;
}
+ private void emitNotifications(final Set<NotificationDefinition> notifications) {
+ for (final NotificationDefinition notification : notifications) {
+ emitNotificationNode(notification);
+ }
+ }
+
private void emitNotificationNode(final NotificationDefinition notification) {
writer.startNotificationNode(notification.getQName());
// FIXME: BUG-2444: *(ifFeatureNode )
+ emitConstraints(notification.getConstraints());
emitDocumentedNode(notification);
emitDataNodeContainer(notification);
emitUnknownStatementNodes(notification.getUnknownSchemaNodes());
import com.google.common.annotations.Beta;
import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
import com.google.common.primitives.UnsignedInteger;
import java.net.URI;
+import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.opendaylight.yangtools.yang.common.QName;
import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
-import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.UniqueConstraint;
+import org.opendaylight.yangtools.yang.model.api.YangStmtMapping;
import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Relative;
+import org.opendaylight.yangtools.yang.model.api.type.ModifierKind;
@Beta
@NotThreadSafe
-final class SchemaToStatementWriterAdaptor implements Rfc6020ModuleWriter {
+final class SchemaToStatementWriterAdaptor implements YangModuleWriter {
private final StatementTextWriter writer;
this.writer = Preconditions.checkNotNull(writer);
}
- public static Rfc6020ModuleWriter from(final StatementTextWriter writer) {
+ public static YangModuleWriter from(final StatementTextWriter writer) {
return new SchemaToStatementWriterAdaptor(writer);
}
writer.startStatement(YangStmtMapping.WHEN);
writer.writeArgument(revisionAwareXPath);
}
+
+ @Override
+ public void startAnydataNode(final QName qName) {
+ writer.startStatement(YangStmtMapping.ANYDATA);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startActionNode(final QName qName) {
+ writer.startStatement(YangStmtMapping.ACTION);
+ writer.writeArgument(qName);
+ }
+
+ @Override
+ public void startModifierNode(final ModifierKind modifier) {
+ writer.startStatement(YangStmtMapping.MODIFIER);
+ writer.writeArgument(modifier.getKeyword());
+ }
+
+ @Override
+ public void startUniqueNode(final UniqueConstraint uniqueConstraint) {
+ writer.startStatement(YangStmtMapping.UNIQUE);
+ final StringBuilder uniqueStr = new StringBuilder();
+ final Collection<Relative> tag = uniqueConstraint.getTag();
+
+ final Iterator<Relative> iter = tag.iterator();
+ while (iter.hasNext()) {
+ uniqueStr.append(
+ String.join("/", Iterables.transform(iter.next().getPathFromRoot(), qn -> qn.getLocalName())));
+ if (iter.hasNext()) {
+ uniqueStr.append(' ');
+ }
+ }
+ writer.writeArgument(uniqueStr.toString());
+ }
}
import org.opendaylight.yangtools.yang.model.api.RevisionAwareXPath;
import org.opendaylight.yangtools.yang.model.api.SchemaPath;
import org.opendaylight.yangtools.yang.model.api.Status;
+import org.opendaylight.yangtools.yang.model.api.UniqueConstraint;
import org.opendaylight.yangtools.yang.model.api.meta.StatementDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.ModifierKind;
-interface Rfc6020ModuleWriter {
+interface YangModuleWriter {
void endNode();
void startWhenNode(RevisionAwareXPath revisionAwareXPath);
+ void startAnydataNode(QName qName);
+
+ void startActionNode(QName qName);
+
+ void startModifierNode(ModifierKind modifier);
+
+ void startUniqueNode(UniqueConstraint uniqueConstraint);
+
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export.test;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import org.custommonkey.xmlunit.Diff;
+import org.custommonkey.xmlunit.ElementNameAndAttributeQualifier;
+import org.custommonkey.xmlunit.XMLAssert;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.SimpleDateFormatUtil;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.export.YinExportUtils;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+public class Bug2444Test {
+ @Test
+ public void test() throws Exception {
+ final SchemaContext schema = YangParserTestUtils.parseYangSources("/bugs/bug2444/yang");
+ assertNotNull(schema);
+
+ final File outDir = new File("target/bug2444-export");
+ outDir.mkdirs();
+
+ for (final Module module : schema.getModules()) {
+ exportModule(schema, module, outDir);
+
+ final OutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+ final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(byteArrayOutputStream);
+ try {
+ YinExportUtils.writeModuleToOutputStream(schema, module, bufferedOutputStream);
+ final String output = byteArrayOutputStream.toString();
+ assertNotNull(output);
+ assertNotEquals(0, output.length());
+
+ final Document doc = YinExportTestUtils.loadDocument(String.format("/bugs/bug2444/yin/%s@%s.yin",
+ module.getName(), SimpleDateFormatUtil.getRevisionFormat().format(module.getRevision())));
+ assertXMLEquals(doc, output);
+ } finally {
+ byteArrayOutputStream.close();
+ bufferedOutputStream.close();
+ }
+ }
+ }
+
+ private static void assertXMLEquals(final Document expectedXMLDoc, final String output)
+ throws SAXException, IOException {
+ final String expected = YinExportTestUtils.toString(expectedXMLDoc.getDocumentElement());
+
+ XMLUnit.setIgnoreWhitespace(true);
+ XMLUnit.setNormalize(true);
+ XMLUnit.setNormalizeWhitespace(true);
+
+ final Diff diff = new Diff(expected, output);
+ diff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
+ XMLAssert.assertXMLEqual(diff, true);
+ }
+
+ private static File exportModule(final SchemaContext schemaContext, final Module module, final File outDir)
+ throws Exception {
+ final File outFile = new File(outDir, YinExportUtils.wellFormedYinName(module.getName(), module.getRevision()));
+ try (OutputStream output = new FileOutputStream(outFile)) {
+ YinExportUtils.writeModuleToOutputStream(schemaContext, module, output);
+ }
+ return outFile;
+ }
+}
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
-import com.google.common.base.Preconditions;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
-import java.io.StringWriter;
import java.net.URISyntaxException;
import javax.xml.stream.XMLStreamException;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.TransformerFactoryConfigurationError;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.ElementNameAndAttributeQualifier;
import org.custommonkey.xmlunit.XMLAssert;
import org.custommonkey.xmlunit.XMLUnit;
import org.junit.Test;
-import org.opendaylight.yangtools.util.xml.UntrustedXML;
import org.opendaylight.yangtools.yang.model.api.Module;
import org.opendaylight.yangtools.yang.model.api.SchemaContext;
import org.opendaylight.yangtools.yang.model.export.YinExportUtils;
import org.opendaylight.yangtools.yang.parser.spi.meta.ReactorException;
import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
import org.w3c.dom.Document;
-import org.w3c.dom.Node;
import org.xml.sax.SAXException;
public class SchemaContextEmitterTest {
final OutputStream byteArrayOutputStream = new ByteArrayOutputStream();
final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(byteArrayOutputStream);
- for (Module module : schemaContext.getModules()) {
+ for (final Module module : schemaContext.getModules()) {
YinExportUtils.writeModuleToOutputStream(schemaContext, module, bufferedOutputStream);
}
assertNotNull(output);
assertNotEquals(0, output.length());
- final Document doc = loadDocument("/schema-context-emitter-test/foo.yin");
- final String expected = toString(doc.getDocumentElement());
+ final Document doc = YinExportTestUtils.loadDocument("/schema-context-emitter-test/foo.yin");
+ final String expected = YinExportTestUtils.toString(doc.getDocumentElement());
XMLUnit.setIgnoreWhitespace(true);
XMLUnit.setNormalize(true);
diff.overrideElementQualifier(new ElementNameAndAttributeQualifier());
XMLAssert.assertXMLEqual(diff, true);
}
-
- private static Document loadDocument(final String xmlPath) throws IOException, SAXException {
- final InputStream resourceAsStream = SchemaContextEmitterTest.class.getResourceAsStream(xmlPath);
- final Document currentConfigElement = readXmlToDocument(resourceAsStream);
- Preconditions.checkNotNull(currentConfigElement);
- return currentConfigElement;
- }
-
- private static Document readXmlToDocument(final InputStream xmlContent) throws IOException, SAXException {
- final Document doc = UntrustedXML.newDocumentBuilder().parse(xmlContent);
- doc.getDocumentElement().normalize();
- return doc;
- }
-
- private static String toString(final Node xml) {
- try {
- final Transformer transformer = TransformerFactory.newInstance().newTransformer();
- transformer.setOutputProperty(OutputKeys.INDENT, "yes");
- transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
-
- final StreamResult result = new StreamResult(new StringWriter());
- final DOMSource source = new DOMSource(xml);
- transformer.transform(source, result);
-
- return result.getWriter().toString();
- } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) {
- throw new RuntimeException("Unable to serialize xml element " + xml, e);
- }
- }
}
--- /dev/null
+/*
+ * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.model.export.test;
+
+import com.google.common.base.Preconditions;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerFactoryConfigurationError;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
+
+public class YinExportTestUtils {
+
+ private YinExportTestUtils() {
+ throw new UnsupportedOperationException("Utility class");
+ }
+
+ static Document loadDocument(final String xmlPath) throws IOException, SAXException {
+ final InputStream resourceAsStream = SchemaContextEmitterTest.class.getResourceAsStream(xmlPath);
+ final Document currentConfigElement = readXmlToDocument(resourceAsStream);
+ Preconditions.checkNotNull(currentConfigElement);
+ return currentConfigElement;
+ }
+
+ static Document readXmlToDocument(final InputStream xmlContent) throws IOException, SAXException {
+ final Document doc = UntrustedXML.newDocumentBuilder().parse(xmlContent);
+ doc.getDocumentElement().normalize();
+ return doc;
+ }
+
+ static String toString(final Node xml) {
+ try {
+ final Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
+ transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
+
+ final StreamResult result = new StreamResult(new StringWriter());
+ final DOMSource source = new DOMSource(xml);
+ transformer.transform(source, result);
+
+ return result.getWriter().toString();
+ } catch (IllegalArgumentException | TransformerFactoryConfigurationError | TransformerException e) {
+ throw new RuntimeException("Unable to serialize xml element " + xml, e);
+ }
+ }
+}
--- /dev/null
+module action {
+ namespace action;
+ prefix ac;
+ yang-version 1.1;
+
+ container root {
+ action a {
+ if-feature "my-feature-1 or my-feature-2";
+ status deprecated;
+ description "decs";
+ reference "ref";
+ typedef my-type {
+ type string;
+ }
+ grouping my-grp {
+ container con-in-grp {
+ }
+ }
+ input {
+ container i {
+ }
+ }
+ output {
+ container o {
+ }
+ }
+ ac:my-ext "arg-val";
+ }
+ }
+
+ extension my-ext {
+ argument my-arg;
+ }
+}
--- /dev/null
+module anydata {
+ namespace anydata;
+ prefix ad;
+ yang-version 1.1;
+
+ anydata my-anydata {
+ when "1!=0";
+ must "1=1";
+ config true;
+ mandatory true;
+ if-feature "my-feature-1 or my-feature-2";
+ status deprecated;
+ description "decs";
+ reference "ref";
+ ad:my-ext "arg-val";
+ }
+
+ extension my-ext {
+ argument my-arg;
+ }
+}
--- /dev/null
+module binary-spec {
+ namespace "binary-spec";
+ prefix bin;
+
+ leaf bin-leaf {
+ type binary {
+ length "1..99";
+ }
+ }
+
+ leaf bin-leaf-2 {
+ type binary {
+ }
+ }
+}
--- /dev/null
+module default {
+ namespace default;
+ prefix def;
+ yang-version 1.1;
+
+ leaf-list my-leaflist-1 {
+ type string;
+ default "def-val-1";
+ default "def-val-2";
+ default "def-val-3";
+ }
+
+ leaf-list my-leaflist-2 {
+ type string;
+ }
+}
--- /dev/null
+module identities {
+ namespace identities;
+ prefix iden;
+ yang-version 1.1;
+
+ identity id-a;
+ identity id-b;
+ identity id-c;
+
+ identity derived-id {
+ base id-a;
+ base id-b;
+ base id-c;
+ }
+
+ leaf idref-leaf {
+ type identityref {
+ base id-a;
+ base id-b;
+ base id-c;
+ }
+ }
+
+ leaf idref-leaf-2 {
+ type identityref {
+ base derived-id;
+ }
+ }
+}
--- /dev/null
+module import-yang1 {
+ namespace "import-yang1";
+ prefix iy1;
+ yang-version 1;
+
+ import action { prefix ac; revision-date 1970-01-01; }
+}
--- /dev/null
+module import {
+ namespace "import";
+ prefix i;
+ yang-version 1.1;
+
+ import action { description "txt"; reference "ref"; prefix ac; revision-date 1970-01-01; }
+}
--- /dev/null
+module leafref-yang1 {
+ namespace leafref-yang1;
+ prefix lr;
+ yang-version 1;
+
+ leaf my-leafref-3 {
+ type leafref {
+ path "/target";
+ }
+ }
+
+ leaf target {
+ type string;
+ }
+}
--- /dev/null
+module leafref {
+ namespace leafref;
+ prefix lr;
+ yang-version 1.1;
+
+ leaf my-leafref {
+ type leafref {
+ path "/target";
+ require-instance false;
+ }
+ }
+
+ leaf my-leafref-2 {
+ type leafref {
+ path "/target";
+ require-instance true;
+ }
+ }
+
+ leaf my-leafref-3 {
+ type leafref {
+ path "/target";
+ }
+ }
+
+ leaf target {
+ type string;
+ }
+}
--- /dev/null
+module modifier-yang1 {
+ namespace modifier-yang1;
+ prefix my1;
+ yang-version 1;
+
+ leaf my-leaf {
+ type string {
+ pattern ".*";
+ }
+ }
+}
--- /dev/null
+module modifier {
+ namespace modifier;
+ prefix m;
+ yang-version 1.1;
+
+ leaf my-leaf {
+ type string {
+ pattern ".*" {
+ modifier invert-match;
+ }
+ }
+ }
+}
--- /dev/null
+module must-yang1 {
+ namespace "must-yang1";
+ prefix muy1;
+ yang-version 1;
+
+ notification n {
+ }
+
+ rpc r {
+ input {
+ }
+ output {
+ }
+ }
+}
--- /dev/null
+module must {
+ namespace "must";
+ prefix mu;
+ yang-version 1.1;
+
+ notification n {
+ must "1!=0";
+ }
+
+ rpc r {
+ input {
+ must "1!=0";
+ }
+ output {
+ must "1!=0";
+ }
+ }
+
+ container root {
+ action a {
+ input {
+ must "1!=0";
+ }
+ output {
+ must "1!=0";
+ }
+ }
+ }
+}
--- /dev/null
+module notification {
+ namespace "notification";
+ prefix n;
+ yang-version 1.1;
+
+ notification n1 {
+ container c {
+ }
+ }
+
+ container r {
+ notification n2 {
+ }
+ }
+
+ list l {
+ key "id";
+ leaf id {
+ type int16;
+ }
+ notification n3 {
+ }
+ }
+
+ augment "/r" {
+ uses grp;
+ notification n4 {
+ }
+ }
+
+ grouping grp {
+ notification n5 {
+ }
+ }
+}
--- /dev/null
+module unique {
+ namespace unique;
+ prefix u;
+
+ list l {
+ key id;
+ leaf id {
+ type string;
+ }
+
+ unique "c1/c2/my-leaf-2";
+ unique "my-container/my-leaf-3";
+ leaf my-leaf-1 {
+ type string;
+ }
+ container c1 {
+ container c2 {
+ leaf my-leaf-2 {
+ type string;
+ }
+ }
+ }
+ container my-container {
+ leaf my-leaf-3 {
+ type string;
+ }
+ }
+ }
+}
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:ac="action"
+ name="action">
+ <yang-version value="1.1"></yang-version>
+ <namespace uri="action"></namespace>
+ <prefix value="ac"></prefix>
+ <revision date="1970-01-01"></revision>
+ <extension name="my-ext">
+ <argument name="my-arg">
+ <yin-element value="false"></yin-element>
+ </argument>
+ <status value="current"></status>
+ </extension>
+ <container name="root">
+ <presence value="false"></presence>
+ <config value="true"></config>
+ <status value="current"></status>
+ <action name="a">
+ <status value="deprecated"></status>
+ <description>
+ <text>decs</text>
+ </description>
+ <reference>
+ <text>ref</text>
+ </reference>
+ <typedef name="my-type">
+ <type name="string"></type>
+ <status value="current"></status>
+ </typedef>
+ <grouping name="my-grp">
+ <status value="current"></status>
+ <container name="con-in-grp">
+ <presence value="false"></presence>
+ <config value="true"></config>
+ <status value="current"></status>
+ </container>
+ </grouping>
+ <input>
+ <container name="i">
+ <presence value="false"></presence>
+ <config value="true"></config>
+ <status value="current"></status>
+ </container>
+ </input>
+ <output>
+ <container name="o">
+ <presence value="false"></presence>
+ <config value="true"></config>
+ <status value="current"></status>
+ </container>
+ </output>
+ <ac:my-ext ac:my-arg="arg-val"></ac:my-ext>
+ </action>
+ </container>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:ad="anydata"
+ name="anydata">
+ <yang-version value="1.1"></yang-version>
+ <namespace uri="anydata"></namespace>
+ <prefix value="ad"></prefix>
+ <revision date="1970-01-01"></revision>
+ <extension name="my-ext">
+ <argument name="my-arg">
+ <yin-element value="false"></yin-element>
+ </argument>
+ <status value="current"></status>
+ </extension>
+ <anydata name="my-anydata">
+ <when condition="1!=0"></when>
+ <must condition="1=1"></must>
+ <config value="true"></config>
+ <mandatory value="true"></mandatory>
+ <status value="deprecated"></status>
+ <description>
+ <text>decs</text>
+ </description>
+ <reference>
+ <text>ref</text>
+ </reference>
+ <ad:my-ext ad:my-arg="arg-val"></ad:my-ext>
+ </anydata>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:bin="binary-spec"
+ name="binary-spec">
+ <yang-version value="1"></yang-version>
+ <namespace uri="binary-spec"></namespace>
+ <prefix value="bin"></prefix>
+ <revision date="1970-01-01"></revision>
+ <leaf name="bin-leaf">
+ <type name="binary">
+ <length value="1..99">
+ <error-message>
+ <value>The argument is out of bounds <1, 99>
+ </value>
+ </error-message>
+ <error-app-tag value="length-out-of-specified-bounds"></error-app-tag>
+ </length>
+ </type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+ <leaf name="bin-leaf-2">
+ <type name="binary"></type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:def="default"
+ name="default">
+ <yang-version value="1.1"></yang-version>
+ <namespace uri="default"></namespace>
+ <prefix value="def"></prefix>
+ <revision date="1970-01-01"></revision>
+ <leaf-list name="my-leaflist-1">
+ <type name="string"></type>
+ <config value="true"></config>
+ <default value="def-val-1"></default>
+ <default value="def-val-2"></default>
+ <default value="def-val-3"></default>
+ <ordered-by value="system"></ordered-by>
+ <status value="current"></status>
+ </leaf-list>
+ <leaf-list name="my-leaflist-2">
+ <type name="string"></type>
+ <config value="true"></config>
+ <ordered-by value="system"></ordered-by>
+ <status value="current"></status>
+ </leaf-list>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:iden="identities"
+ name="identities">
+ <yang-version value="1.1"></yang-version>
+ <namespace uri="identities"></namespace>
+ <prefix value="iden"></prefix>
+ <revision date="1970-01-01"></revision>
+ <identity name="id-a">
+ <status value="current"></status>
+ </identity>
+ <identity name="id-b">
+ <status value="current"></status>
+ </identity>
+ <identity name="id-c">
+ <status value="current"></status>
+ </identity>
+ <identity name="derived-id">
+ <base name="id-a"></base>
+ <base name="id-b"></base>
+ <base name="id-c"></base>
+ <status value="current"></status>
+ </identity>
+ <leaf name="idref-leaf">
+ <type name="identityref">
+ <base name="id-a"></base>
+ <base name="id-b"></base>
+ <base name="id-c"></base>
+ </type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+ <leaf name="idref-leaf-2">
+ <type name="identityref">
+ <base name="derived-id"></base>
+ </type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:iy1="import-yang1"
+ xmlns:ac="action" name="import-yang1">
+ <yang-version value="1"></yang-version>
+ <namespace uri="import-yang1"></namespace>
+ <prefix value="iy1"></prefix>
+ <import module="action">
+ <prefix value="ac"></prefix>
+ <revision-date date="1970-01-01"></revision-date>
+ </import>
+ <revision date="1970-01-01"></revision>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:i="import"
+ xmlns:ac="action" name="import">
+ <yang-version value="1.1"></yang-version>
+ <namespace uri="import"></namespace>
+ <prefix value="i"></prefix>
+ <import module="action">
+ <description>
+ <text>txt</text>
+ </description>
+ <reference>
+ <text>ref</text>
+ </reference>
+ <prefix value="ac"></prefix>
+ <revision-date date="1970-01-01"></revision-date>
+ </import>
+ <revision date="1970-01-01"></revision>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:lr="leafref-yang1"
+ name="leafref-yang1">
+ <yang-version value="1"></yang-version>
+ <namespace uri="leafref-yang1"></namespace>
+ <prefix value="lr"></prefix>
+ <revision date="1970-01-01"></revision>
+ <leaf name="my-leafref-3">
+ <type name="leafref">
+ <path value="/target"></path>
+ </type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+ <leaf name="target">
+ <type name="string"></type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:lr="leafref"
+ name="leafref">
+ <yang-version value="1.1"></yang-version>
+ <namespace uri="leafref"></namespace>
+ <prefix value="lr"></prefix>
+ <revision date="1970-01-01"></revision>
+ <leaf name="my-leafref">
+ <type name="leafref">
+ <path value="/target"></path>
+ <require-instance value="false"></require-instance>
+ </type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+ <leaf name="my-leafref-2">
+ <type name="leafref">
+ <path value="/target"></path>
+ <require-instance value="true"></require-instance>
+ </type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+ <leaf name="my-leafref-3">
+ <type name="leafref">
+ <path value="/target"></path>
+ <require-instance value="false"></require-instance>
+ </type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+ <leaf name="target">
+ <type name="string"></type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:my1="modifier-yang1"
+ name="modifier-yang1">
+ <yang-version value="1"></yang-version>
+ <namespace uri="modifier-yang1"></namespace>
+ <prefix value="my1"></prefix>
+ <revision date="1970-01-01"></revision>
+ <leaf name="my-leaf">
+ <type name="string">
+ <length value="0..2147483647">
+ <error-message>
+ <value>The argument is out of bounds <0,
+ 2147483647></value>
+ </error-message>
+ <error-app-tag value="length-out-of-specified-bounds"></error-app-tag>
+ </length>
+ <pattern value=".*">
+ <error-message>
+ <value>Supplied value does not match the regular
+ expression ^.*$.</value>
+ </error-message>
+ <error-app-tag value="invalid-regular-expression"></error-app-tag>
+ </pattern>
+ </type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:m="modifier"
+ name="modifier">
+ <yang-version value="1.1"></yang-version>
+ <namespace uri="modifier"></namespace>
+ <prefix value="m"></prefix>
+ <revision date="1970-01-01"></revision>
+ <leaf name="my-leaf">
+ <type name="string">
+ <length value="0..2147483647">
+ <error-message>
+ <value>The argument is out of bounds <0,
+ 2147483647></value>
+ </error-message>
+ <error-app-tag value="length-out-of-specified-bounds"></error-app-tag>
+ </length>
+ <pattern value=".*">
+ <error-message>
+ <value>Supplied value does not match the regular
+ expression ^.*$.</value>
+ </error-message>
+ <error-app-tag value="invalid-regular-expression"></error-app-tag>
+ <modifier value="invert-match"></modifier>
+ </pattern>
+ </type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:muy1="must-yang1"
+ name="must-yang1">
+ <yang-version value="1"></yang-version>
+ <namespace uri="must-yang1"></namespace>
+ <prefix value="muy1"></prefix>
+ <revision date="1970-01-01"></revision>
+ <rpc name="r">
+ <status value="current"></status>
+ <input></input>
+ <output></output>
+ </rpc>
+ <notification name="n">
+ <status value="current"></status>
+ </notification>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:mu="must"
+ name="must">
+ <yang-version value="1.1"></yang-version>
+ <namespace uri="must"></namespace>
+ <prefix value="mu"></prefix>
+ <revision date="1970-01-01"></revision>
+ <container name="root">
+ <presence value="false"></presence>
+ <config value="true"></config>
+ <status value="current"></status>
+ <action name="a">
+ <status value="current"></status>
+ <input>
+ <must condition="1!=0"></must>
+ </input>
+ <output>
+ <must condition="1!=0"></must>
+ </output>
+ </action>
+ </container>
+ <rpc name="r">
+ <status value="current"></status>
+ <input>
+ <must condition="1!=0"></must>
+ </input>
+ <output>
+ <must condition="1!=0"></must>
+ </output>
+ </rpc>
+ <notification name="n">
+ <must condition="1!=0"></must>
+ <status value="current"></status>
+ </notification>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:n="notification"
+ name="notification">
+ <yang-version value="1.1"></yang-version>
+ <namespace uri="notification"></namespace>
+ <prefix value="n"></prefix>
+ <revision date="1970-01-01"></revision>
+ <grouping name="grp">
+ <status value="current"></status>
+ <notification name="n5">
+ <status value="current"></status>
+ </notification>
+ </grouping>
+ <container name="r">
+ <presence value="false"></presence>
+ <config value="true"></config>
+ <status value="current"></status>
+ <notification name="n2">
+ <status value="current"></status>
+ </notification>
+ <notification name="n4">
+ <status value="current"></status>
+ </notification>
+ <notification name="n5">
+ <status value="current"></status>
+ </notification>
+ </container>
+ <list name="l">
+ <key value="id"></key>
+ <config value="true"></config>
+ <ordered-by value="system"></ordered-by>
+ <status value="current"></status>
+ <leaf name="id">
+ <type name="int16"></type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+ <notification name="n3">
+ <status value="current"></status>
+ </notification>
+ </list>
+ <augment target-node="/r">
+ <status value="current"></status>
+ <uses name="grp"></uses>
+ <notification name="n5">
+ <status value="current"></status>
+ </notification>
+ <notification name="n4">
+ <status value="current"></status>
+ </notification>
+ </augment>
+ <notification name="n1">
+ <status value="current"></status>
+ <container name="c">
+ <presence value="false"></presence>
+ <config value="true"></config>
+ <status value="current"></status>
+ </container>
+ </notification>
+</module>
\ No newline at end of file
--- /dev/null
+<module xmlns="urn:ietf:params:xml:ns:yang:yin:1" xmlns:u="unique"
+ name="unique">
+ <yang-version value="1"></yang-version>
+ <namespace uri="unique"></namespace>
+ <prefix value="u"></prefix>
+ <revision date="1970-01-01"></revision>
+ <list name="l">
+ <key value="id"></key>
+ <unique tag="c1/c2/my-leaf-2"></unique>
+ <unique tag="my-container/my-leaf-3"></unique>
+ <config value="true"></config>
+ <ordered-by value="system"></ordered-by>
+ <status value="current"></status>
+ <leaf name="id">
+ <type name="string"></type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+ <leaf name="my-leaf-1">
+ <type name="string"></type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+ <container name="c1">
+ <presence value="false"></presence>
+ <config value="true"></config>
+ <status value="current"></status>
+ <container name="c2">
+ <presence value="false"></presence>
+ <config value="true"></config>
+ <status value="current"></status>
+ <leaf name="my-leaf-2">
+ <type name="string"></type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+ </container>
+ </container>
+ <container name="my-container">
+ <presence value="false"></presence>
+ <config value="true"></config>
+ <status value="current"></status>
+ <leaf name="my-leaf-3">
+ <type name="string"></type>
+ <config value="true"></config>
+ <mandatory value="false"></mandatory>
+ <status value="current"></status>
+ </leaf>
+ </container>
+ </list>
+</module>
\ No newline at end of file
<yang-version value="1"></yang-version>
<namespace uri="foo-namespace"></namespace>
<prefix value="foo-prefix"></prefix>
- <organization>
- <text></text>
- </organization>
- <contact>
- <text></text>
- </contact>
<revision date="2016-08-05"></revision>
<extension name="test-extension">
<status value="current"></status>