Bug 5824: Migrate netconf to the new XML parser 50/60250/4
authorIgor Foltin <igor.foltin@pantheon.tech>
Wed, 12 Jul 2017 15:13:19 +0000 (17:13 +0200)
committerIgor Foltin <igor.foltin@pantheon.tech>
Tue, 18 Jul 2017 06:15:48 +0000 (06:15 +0000)
Migrate netconf components to the new XML parser from YANG tools.

Change-Id: I42899d4d07cb2f917c50fa862cd6453bb0a8764d
Signed-off-by: Igor Foltin <igor.foltin@pantheon.tech>
netconf/mdsal-netconf-connector/src/main/java/org/opendaylight/netconf/mdsal/connector/ops/RuntimeRpc.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/LibraryModulesSchemas.java
netconf/sal-netconf-connector/src/main/java/org/opendaylight/netconf/sal/connect/netconf/schema/mapping/NetconfMessageTransformer.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfStateSchemasTest.java
netconf/sal-netconf-connector/src/test/java/org/opendaylight/netconf/sal/connect/netconf/NetconfToNotificationTest.java
netconf/tools/netconf-cli/src/main/java/org/opendaylight/netconf/cli/reader/impl/AnyXmlReader.java

index 2b18e2c2c569e1624a51ddaf15e5f8e1f959827d..18923edb7b4d21f81a82918d2d441889495c3e02 100644 (file)
@@ -12,6 +12,7 @@ import com.google.common.base.Optional;
 import com.google.common.base.Throwables;
 import com.google.common.util.concurrent.CheckedFuture;
 import java.io.IOException;
+import java.io.StringReader;
 import java.net.URI;
 import java.util.Collection;
 import java.util.Collections;
@@ -31,19 +32,22 @@ import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcService;
+import org.opendaylight.netconf.api.NetconfDocumentedException;
 import org.opendaylight.netconf.api.xml.XmlNetconfConstants;
 import org.opendaylight.netconf.mapping.api.HandlingPriority;
 import org.opendaylight.netconf.mapping.api.NetconfOperationChainedExecution;
 import org.opendaylight.netconf.mdsal.connector.CurrentSchemaContext;
 import org.opendaylight.netconf.util.mapping.AbstractSingletonNetconfOperation;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.codec.xml.XMLStreamNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
 import org.opendaylight.yangtools.yang.data.impl.schema.SchemaOrderedNormalizedNodeWriter;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
@@ -254,12 +258,26 @@ public class RuntimeRpc extends AbstractSingletonNetconfOperation {
      * @param input   input container schema node, or null if rpc does not take any input
      * @return parsed rpc into normalized node, or null if input schema is null
      */
+    @SuppressWarnings("checkstyle:IllegalCatch")
     @Nullable
-    private NormalizedNode<?, ?> rpcToNNode(final XmlElement element, @Nullable final ContainerSchemaNode input) {
-        return input.getChildNodes().isEmpty() ? null : DomToNormalizedNodeParserFactory
-                .getInstance(DomUtils.defaultValueCodecProvider(), schemaContext.getCurrentContext())
-                .getContainerNodeParser()
-                .parse(Collections.singletonList(element.getDomElement()), input);
+    private NormalizedNode<?, ?> rpcToNNode(final XmlElement element, @Nullable final ContainerSchemaNode input)
+            throws DocumentedException {
+        if (input.getChildNodes().isEmpty()) {
+            return null;
+        }
+
+        final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+        final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+        final XmlParserStream xmlParser = XmlParserStream.create(writer, schemaContext.getCurrentContext(), input);
+
+        try {
+            xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(XmlUtil.toString(element))));
+        } catch (final Exception ex) {
+            throw new NetconfDocumentedException("Error parsing input: " + ex.getMessage(), ex, ErrorType.PROTOCOL,
+                    ErrorTag.MALFORMED_MESSAGE, ErrorSeverity.ERROR);
+        }
+
+        return resultHolder.getResult();
     }
 
 }
index f00668a09328e026104de66c989851af0f70ea2b..8a4ea7efd7284c1c66cecb14fa3edc8e2a193eaf 100644 (file)
@@ -22,7 +22,7 @@ import com.google.gson.stream.JsonReader;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.io.StringWriter;
+import java.io.StringReader;
 import java.net.HttpURLConnection;
 import java.net.MalformedURLException;
 import java.net.URI;
@@ -35,12 +35,6 @@ import java.util.Set;
 import java.util.concurrent.ExecutionException;
 import java.util.regex.Pattern;
 import javax.xml.parsers.DocumentBuilder;
-import javax.xml.transform.OutputKeys;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.TransformerException;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.stream.StreamResult;
 import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
 import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
@@ -61,12 +55,10 @@ import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.codec.gson.JsonParserStream;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
 import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
-import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.model.repo.api.RevisionSourceIdentifier;
 import org.opendaylight.yangtools.yang.model.repo.api.SourceIdentifier;
@@ -75,7 +67,6 @@ import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
-import org.xml.sax.SAXException;
 
 /**
  * Holds URLs with YANG schema resources for all yang modules reported in
@@ -319,9 +310,8 @@ public class LibraryModulesSchemas implements NetconfDeviceSchemas {
                 ? Optional.of(resultHolder.getResult()) : Optional.<NormalizedNode<?, ?>>absent();
     }
 
+    @SuppressWarnings("checkstyle:IllegalCatch")
     private static Optional<NormalizedNode<?, ?>> readXml(final InputStream in) {
-        final DomToNormalizedNodeParserFactory parserFactory =
-                DomToNormalizedNodeParserFactory.getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, LIBRARY_CONTEXT);
         try {
             final DocumentBuilder docBuilder = UntrustedXML.newDocumentBuilder();
 
@@ -342,16 +332,16 @@ public class LibraryModulesSchemas implements NetconfDeviceSchemas {
                 }
             }
 
-            final Transformer transformer = TransformerFactory.newInstance().newTransformer();
-            final StringWriter sw = new StringWriter();
-            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
-            transformer.transform(new DOMSource(doc), new StreamResult(sw));
-            final NormalizedNode<?, ?> parsed =
-                    parserFactory.getContainerNodeParser()
-                            .parse(Collections.singleton(XmlUtil.readXmlToElement(sw.toString())),
-                            (ContainerSchemaNode) LIBRARY_CONTEXT.getDataChildByName(ModulesState.QNAME));
+            final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+            final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+            final XmlParserStream xmlParser = XmlParserStream.create(writer, LIBRARY_CONTEXT,
+                    LIBRARY_CONTEXT.getDataChildByName(ModulesState.QNAME));
+
+            xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(XmlUtil.toString(
+                    doc.getDocumentElement(), false))));
+            final NormalizedNode<?, ?> parsed = resultHolder.getResult();
             return Optional.of(parsed);
-        } catch (final SAXException | IOException | TransformerException e) {
+        } catch (final Exception e) {
             LOG.warn("Unable to parse yang library xml content", e);
         }
 
index 734abb7978b910f0d5c3bf0ca4a069926674026c..89d9c19850ec9c51121677d4843bccb9983dfe89 100644 (file)
@@ -16,6 +16,7 @@ import com.google.common.collect.Maps;
 import com.google.common.collect.Multimap;
 import com.google.common.collect.Multimaps;
 import java.io.IOException;
+import java.io.StringReader;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -26,6 +27,7 @@ import javax.xml.stream.XMLStreamException;
 import javax.xml.transform.dom.DOMResult;
 import org.opendaylight.controller.config.util.xml.MissingNameSpaceException;
 import org.opendaylight.controller.config.util.xml.XmlElement;
+import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.md.sal.dom.api.DOMEvent;
 import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcResult;
@@ -34,13 +36,16 @@ import org.opendaylight.netconf.api.NetconfMessage;
 import org.opendaylight.netconf.sal.connect.api.MessageTransformer;
 import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransformUtil;
 import org.opendaylight.netconf.sal.connect.util.MessageCounter;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
 import org.opendaylight.yangtools.yang.model.api.RpcDefinition;
@@ -61,7 +66,8 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
     private final MessageCounter counter;
     private final Map<QName, RpcDefinition> mappedRpcs;
     private final Multimap<QName, NotificationDefinition> mappedNotifications;
-    private final DomToNormalizedNodeParserFactory parserFactory;
+
+    private final boolean strictParsing;
 
     public NetconfMessageTransformer(final SchemaContext schemaContext, final boolean strictParsing) {
         this(schemaContext, strictParsing, BaseSchema.BASE_NETCONF_CTX);
@@ -71,14 +77,14 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
                                      final BaseSchema baseSchema) {
         this.counter = new MessageCounter();
         this.schemaContext = schemaContext;
-        parserFactory = DomToNormalizedNodeParserFactory
-                .getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, schemaContext, strictParsing);
         mappedRpcs = Maps.uniqueIndex(schemaContext.getOperations(), SchemaNode::getQName);
         mappedNotifications = Multimaps.index(schemaContext.getNotifications(),
             node -> node.getQName().withoutRevision());
         this.baseSchema = baseSchema;
+        this.strictParsing = strictParsing;
     }
 
+    @SuppressWarnings("checkstyle:IllegalCatch")
     @Override
     public synchronized DOMNotification toNotification(final NetconfMessage message) {
         final Map.Entry<Date, XmlElement> stripped = NetconfMessageTransformUtil.stripNotification(message);
@@ -103,9 +109,14 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
         final Element element = stripped.getValue().getDomElement();
         final ContainerNode content;
         try {
-            content = parserFactory.getContainerNodeParser().parse(Collections.singleton(element),
-                notificationAsContainerSchemaNode);
-        } catch (IllegalArgumentException e) {
+            final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+            final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+            final XmlParserStream xmlParser = XmlParserStream.create(writer, schemaContext,
+                    notificationAsContainerSchemaNode, strictParsing);
+
+            xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(XmlUtil.toString(element))));
+            content = (ContainerNode) resultHolder.getResult();
+        } catch (final Exception e) {
             throw new IllegalArgumentException(String.format("Failed to parse notification %s", element), e);
         }
         return new NetconfDeviceNotification(content, stripped.getKey());
@@ -169,7 +180,7 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
                 || rpc.getNamespace().equals(NetconfMessageTransformUtil.CREATE_SUBSCRIPTION_RPC_QNAME.getNamespace());
     }
 
-
+    @SuppressWarnings("checkstyle:IllegalCatch")
     @Override
     public synchronized DOMRpcResult toRpcResult(final NetconfMessage message, final SchemaPath rpc) {
         final NormalizedNode<?, ?> normalizedNode;
@@ -181,9 +192,14 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
             final ContainerNode dataNode;
 
             try {
-                dataNode =
-                        parserFactory.getContainerNodeParser().parse(Collections.singleton(xmlData), schemaForDataRead);
-            } catch (IllegalArgumentException e) {
+                final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+                final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+                final XmlParserStream xmlParser = XmlParserStream.create(writer, schemaContext, schemaForDataRead,
+                        strictParsing);
+
+                xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(XmlUtil.toString(xmlData))));
+                dataNode = (ContainerNode) resultHolder.getResult();
+            } catch (final Exception e) {
                 throw new IllegalArgumentException(String.format("Failed to parse data response %s", xmlData), e);
             }
 
@@ -216,9 +232,14 @@ public class NetconfMessageTransformer implements MessageTransformer<NetconfMess
             } else {
                 final Element element = message.getDocument().getDocumentElement();
                 try {
-                    normalizedNode = parserFactory.getContainerNodeParser().parse(Collections.singleton(element),
-                        rpcDefinition.getOutput());
-                } catch (IllegalArgumentException e) {
+                    final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+                    final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+                    final XmlParserStream xmlParser = XmlParserStream.create(writer, schemaContext,
+                            rpcDefinition.getOutput(), strictParsing);
+
+                    xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(XmlUtil.toString(element))));
+                    normalizedNode = resultHolder.getResult();
+                } catch (final Exception e) {
                     throw new IllegalArgumentException(String.format("Failed to parse RPC response %s", element), e);
                 }
             }
index fd2ea869c72a2a0db4dec51d226ecf29f5d46d92..3c8cac318136b4e89618db2fd952c8ad383c19ae 100644 (file)
@@ -33,7 +33,6 @@ import org.junit.Before;
 import org.junit.Test;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcException;
 import org.opendaylight.controller.md.sal.dom.api.DOMRpcImplementationNotAvailableException;
@@ -46,22 +45,22 @@ import org.opendaylight.netconf.sal.connect.netconf.util.NetconfMessageTransform
 import org.opendaylight.netconf.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfState;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.Schemas;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.common.RpcError;
 import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlUtils;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
 import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.w3c.dom.Document;
-import org.w3c.dom.Element;
 
 public class NetconfStateSchemasTest {
 
@@ -84,13 +83,14 @@ public class NetconfStateSchemasTest {
         final DataSchemaNode schemasNode =
                 ((ContainerSchemaNode) schemaContext
                         .getDataChildByName(NetconfState.QNAME)).getDataChildByName(Schemas.QNAME);
-        final Document schemasXml =
-                XmlUtil.readXmlToDocument(getClass().getResourceAsStream("/netconf-state.schemas.payload.xml"));
-        final ToNormalizedNodeParser<Element, ContainerNode, ContainerSchemaNode> containerNodeParser =
-                DomToNormalizedNodeParserFactory
-                    .getInstance(XmlUtils.DEFAULT_XML_CODEC_PROVIDER, schemaContext, false).getContainerNodeParser();
-        compositeNodeSchemas = containerNodeParser
-                .parse(Collections.singleton(schemasXml.getDocumentElement()), (ContainerSchemaNode) schemasNode);
+
+        final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+        final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+        final XmlParserStream xmlParser = XmlParserStream.create(writer, schemaContext, schemasNode, false);
+
+        xmlParser.parse(UntrustedXML.createXMLStreamReader(getClass().getResourceAsStream(
+                "/netconf-state.schemas.payload.xml")));
+        compositeNodeSchemas = (ContainerNode) resultHolder.getResult();
 
     }
 
index 20502f45e982088b2f74d0cb588c5273ee204e64..0b37a87e9320b6cd3c07dc244e45cbb5e7f92df6 100644 (file)
@@ -66,7 +66,7 @@ public class NetconfToNotificationTest {
         return context;
     }
 
-    @Test(expected =  IllegalStateException.class)
+    @Test(expected =  IllegalArgumentException.class)
     public void testMostRecentWrongYangModel() throws Exception {
         final SchemaContext schemaContext = getNotificationSchemaContext(getClass(), true);
         messageTransformer = new NetconfMessageTransformer(schemaContext, true);
index cdc30830639381fb1865eac27873ae4c97ef2267..b625a9afb44843e458d60336e27e458692ccc45c 100644 (file)
@@ -12,26 +12,26 @@ import static org.opendaylight.netconf.cli.io.IOUtil.listType;
 
 import com.google.common.base.Optional;
 import java.io.IOException;
+import java.io.StringReader;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
-import org.opendaylight.controller.config.util.xml.XmlUtil;
 import org.opendaylight.netconf.cli.io.BaseConsoleContext;
 import org.opendaylight.netconf.cli.io.ConsoleContext;
 import org.opendaylight.netconf.cli.io.ConsoleIO;
 import org.opendaylight.netconf.cli.reader.AbstractReader;
 import org.opendaylight.netconf.cli.reader.ReadingException;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.codec.xml.XmlParserStream;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNormalizedNodeStreamWriter;
+import org.opendaylight.yangtools.yang.data.impl.schema.NormalizedNodeResult;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser.DomToNormalizedNodeParserFactory;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.w3c.dom.Document;
-import org.xml.sax.SAXException;
 
 public class AnyXmlReader extends AbstractReader<AnyXmlSchemaNode> {
 
@@ -69,16 +69,16 @@ public class AnyXmlReader extends AbstractReader<AnyXmlSchemaNode> {
         return newNodes;
     }
 
+    @SuppressWarnings("checkstyle:IllegalCatch")
     private Optional<DataContainerChild<?, ?>> tryParse(final String rawValue, final AnyXmlSchemaNode schemaNode) {
         try {
-            final Document dom = XmlUtil.readXmlToDocument(rawValue);
-            return Optional.of(
-                    DomToNormalizedNodeParserFactory
-                            .getInstance(DomUtils.defaultValueCodecProvider(), getSchemaContext())
-                            .getAnyXmlNodeParser()
-                            .parse(Collections.singletonList(dom.getDocumentElement()), schemaNode)
-            );
-        } catch (SAXException | IOException e) {
+            final NormalizedNodeResult resultHolder = new NormalizedNodeResult();
+            final NormalizedNodeStreamWriter writer = ImmutableNormalizedNodeStreamWriter.from(resultHolder);
+            final XmlParserStream xmlParser = XmlParserStream.create(writer, getSchemaContext(), schemaNode);
+
+            xmlParser.parse(UntrustedXML.createXMLStreamReader(new StringReader(rawValue)));
+            return Optional.of((DataContainerChild<?, ?>) resultHolder.getResult());
+        } catch (final Exception e) {
             // TODO log
             return Optional.absent();
         }