From d42fc809d1d74240b7933d74cdbaff428773ad26 Mon Sep 17 00:00:00 2001 From: Tomas Olvecky Date: Wed, 14 May 2014 17:34:11 +0200 Subject: [PATCH 1/1] Bug 992 - Fix broken netconf xml serialization. Empty commit and restart triggered xml deserialization errors in netconf. The problem is in type and name elements - they should not be prefixed with 'prefix:'. This fix triggers other bugs in md-sal modules, tracked as dependencies of this bug. To test proper (de)serialization with this fix, 01-netconf-connector.xml and 02-clustering.xml must be delted. Change-Id: I54d6ab23ec27ccbed924bf6abff95736f49dd5a3 Signed-off-by: Tomas Olvecky --- .../SimpleAttributeReadingStrategy.java | 20 +----- .../ObjectNameAttributeWritingStrategy.java | 5 +- ...leIdentityRefAttributeWritingStrategy.java | 5 +- .../mapping/config/ModuleConfig.java | 22 +++--- .../mapping/config/Services.java | 8 ++- .../NetconfMappingTest.java | 67 +++++++++---------- .../controller/netconf/it/NetconfITTest.java | 8 +-- .../netconf/util/xml/XmlElement.java | 64 ++++++++++-------- .../controller/netconf/util/xml/XmlUtil.java | 33 +++++---- 9 files changed, 112 insertions(+), 120 deletions(-) diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java index cb8f66081b..8f6a7cd1e4 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/fromxml/SimpleAttributeReadingStrategy.java @@ -12,13 +12,8 @@ import com.google.common.base.Preconditions; import java.util.List; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.util.xml.XmlElement; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStrategy { - private static final Logger logger = LoggerFactory.getLogger(SimpleAttributeReadingStrategy.class); - - public SimpleAttributeReadingStrategy(String nullableDefault) { super(nullableDefault); } @@ -29,20 +24,7 @@ public class SimpleAttributeReadingStrategy extends AbstractAttributeReadingStra Preconditions.checkState(configNodes.size() == 1, "This element should be present only once " + xmlElement + " but was " + configNodes.size()); - String textContent = ""; - try{ - textContent = readElementContent(xmlElement); - }catch(IllegalStateException | NullPointerException e) { - // yuma sends for empty value instead of - logger.warn("Ignoring exception caused by failure to read text element", e); - } - - if (null == textContent){ - throw new NetconfDocumentedException(String.format("This element should contain text %s", xmlElement), - NetconfDocumentedException.ErrorType.application, - NetconfDocumentedException.ErrorTag.invalid_value, - NetconfDocumentedException.ErrorSeverity.error); - } + String textContent = readElementContent(xmlElement); return AttributeConfigElement.create(postprocessNullableDefault(getNullableDefault()), postprocessParsedValue(textContent)); } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java index 66b945d14b..68c8c6fce3 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/ObjectNameAttributeWritingStrategy.java @@ -40,8 +40,9 @@ public class ObjectNameAttributeWritingStrategy implements AttributeWritingStrat String refName = ((ObjectNameAttributeMappingStrategy.MappedDependency) value).getRefName(); String namespaceForType = ((ObjectNameAttributeMappingStrategy.MappedDependency) value).getNamespace(); - Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlUtil.createPrefixedValue(XmlNetconfConstants.PREFIX, XmlNetconfConstants.TYPE_KEY), XmlNetconfConstants.PREFIX, - moduleName, Optional.of(namespaceForType)); + Element typeElement = XmlUtil.createTextElementWithNamespacedContent(document, XmlNetconfConstants.TYPE_KEY, XmlNetconfConstants.PREFIX, + namespaceForType, moduleName); + innerNode.appendChild(typeElement); final Element nameElement = XmlUtil.createTextElement(document, XmlNetconfConstants.NAME_KEY, refName, Optional.absent()); diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java index ed3bb2a9d9..a2b8e0bfdf 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/attributes/toxml/SimpleIdentityRefAttributeWritingStrategy.java @@ -43,9 +43,8 @@ public class SimpleIdentityRefAttributeWritingStrategy extends SimpleAttributeWr @Override protected Element createElement(Document doc, String key, String value, Optional namespace) { QName qName = QName.create(value); - String identity = qName.getLocalName(); + String identityValue = qName.getLocalName(); String identityNamespace = qName.getNamespace().toString(); - Element element = XmlUtil.createPrefixedTextElement(doc, XmlUtil.createPrefixedValue(PREFIX, key), PREFIX, identity, Optional.of(identityNamespace)); - return element; + return XmlUtil.createTextElementWithNamespacedContent(doc, key, PREFIX, identityNamespace, identityValue); } } diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java index a5a625a2d6..6a17e97350 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/ModuleConfig.java @@ -60,19 +60,17 @@ public class ModuleConfig { public Element toXml(ObjectName instanceON, ServiceRegistryWrapper depTracker, Document document, String namespace) { Element root = XmlUtil.createElement(document, XmlNetconfConstants.MODULE_KEY, Optional.absent()); - // Xml.addNamespaceAttr(document, root, namespace); - final String prefix = getPrefix(); - Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlUtil.createPrefixedValue(prefix, XmlNetconfConstants.TYPE_KEY), prefix, - moduleName, Optional.of(namespace)); - // Xml.addNamespaceAttr(document, typeElement, - // XMLUtil.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); + // type belongs to config.yang namespace, but needs to be prefix:moduleName + + Element typeElement = XmlUtil.createTextElementWithNamespacedContent(document, XmlNetconfConstants.TYPE_KEY, + XmlNetconfConstants.PREFIX, namespace, moduleName); + root.appendChild(typeElement); + // name belongs to config.yang namespace + String instanceName = ObjectNameUtil.getInstanceName(instanceON); + Element nameElement = XmlUtil.createTextElement(document, XmlNetconfConstants.NAME_KEY, instanceName, Optional.absent()); - Element nameElement = XmlUtil.createTextElement(document, XmlUtil.createPrefixedValue(prefix, XmlNetconfConstants.NAME_KEY), - ObjectNameUtil.getInstanceName(instanceON), Optional.of(namespace)); - // Xml.addNamespaceAttr(document, nameElement, - // XMLUtil.URN_OPENDAYLIGHT_PARAMS_XML_NS_YANG_CONTROLLER_CONFIG); root.appendChild(nameElement); root = instanceConfig.toXml(instanceON, depTracker, namespace, document, root); @@ -80,10 +78,6 @@ public class ModuleConfig { return root; } - private String getPrefix() { - return XmlNetconfConstants.PREFIX; - } - public ModuleElementResolved fromXml(XmlElement moduleElement, ServiceRegistryWrapper depTracker, String instanceName, String moduleNamespace, EditStrategyType defaultStrategy, Map> identityMap) throws NetconfDocumentedException { diff --git a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java index eb5c018cf3..559de7a756 100644 --- a/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java +++ b/opendaylight/netconf/config-netconf-connector/src/main/java/org/opendaylight/controller/netconf/confignetconfconnector/mapping/config/Services.java @@ -131,11 +131,15 @@ public final class Services { for (String namespace : mappedServices.keySet()) { for (Entry> serviceEntry : mappedServices.get(namespace).entrySet()) { + // service belongs to config.yang namespace Element serviceElement = XmlUtil.createElement(document, SERVICE_KEY, Optional.absent()); root.appendChild(serviceElement); - Element typeElement = XmlUtil.createPrefixedTextElement(document, XmlUtil.createPrefixedValue(XmlNetconfConstants.PREFIX, TYPE_KEY), XmlNetconfConstants.PREFIX, - serviceEntry.getKey(), Optional.of(namespace)); + // type belongs to config.yang namespace + String serviceType = serviceEntry.getKey(); + Element typeElement = XmlUtil.createTextElementWithNamespacedContent(document, XmlNetconfConstants.TYPE_KEY, + XmlNetconfConstants.PREFIX, namespace, serviceType); + serviceElement.appendChild(typeElement); for (Entry instanceEntry : serviceEntry.getValue().entrySet()) { diff --git a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java index 2e8d1f64ab..f8d21e401c 100644 --- a/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java +++ b/opendaylight/netconf/config-netconf-connector/src/test/java/org/opendaylight/controller/netconf/confignetconfconnector/NetconfMappingTest.java @@ -8,11 +8,42 @@ package org.opendaylight.controller.netconf.confignetconfconnector; +import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElement; +import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText; +import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElement; + import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.math.BigInteger; +import java.net.URISyntaxException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import javax.management.InstanceAlreadyExistsException; +import javax.management.InstanceNotFoundException; +import javax.management.ObjectName; +import javax.xml.parsers.ParserConfigurationException; import org.custommonkey.xmlunit.AbstractNodeTester; import org.custommonkey.xmlunit.NodeTest; import org.custommonkey.xmlunit.NodeTestException; @@ -83,38 +114,6 @@ import org.w3c.dom.Text; import org.w3c.dom.traversal.DocumentTraversal; import org.xml.sax.SAXException; -import javax.management.InstanceAlreadyExistsException; -import javax.management.InstanceNotFoundException; -import javax.management.ObjectName; -import javax.xml.parsers.ParserConfigurationException; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.math.BigInteger; -import java.net.URISyntaxException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.doReturn; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyNoMoreInteractions; -import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElement; -import static org.opendaylight.controller.netconf.util.test.XmlUnitUtil.assertContainsElementWithText; -import static org.opendaylight.controller.netconf.util.xml.XmlUtil.readXmlToElement; - public class NetconfMappingTest extends AbstractConfigTest { private static final Logger logger = LoggerFactory.getLogger(NetconfMappingTest.class); @@ -573,7 +572,7 @@ public class NetconfMappingTest extends AbstractConfigTest { String enumContent = "TWO"; for (XmlElement moduleElement : modulesElement.getChildElements("module")) { - String name = moduleElement.getOnlyChildElement("prefix:name").getTextContent(); + String name = moduleElement.getOnlyChildElement("name").getTextContent(); if(name.equals(INSTANCE_NAME)) { XmlElement enumAttr = moduleElement.getOnlyChildElement(enumName); assertEquals(enumContent, enumAttr.getTextContent()); @@ -599,7 +598,7 @@ public class NetconfMappingTest extends AbstractConfigTest { for (XmlElement moduleElement : modulesElement.getChildElements("module")) { for (XmlElement type : moduleElement.getChildElements("type")) { - if (type.getNamespace() != null) { + if (type.getNamespaceOptionally().isPresent()) { configAttributeType.add(type.getTextContent()); } } diff --git a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java index cd53995bce..fd43f67c05 100644 --- a/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java +++ b/opendaylight/netconf/netconf-it/src/test/java/org/opendaylight/controller/netconf/it/NetconfITTest.java @@ -386,10 +386,10 @@ public class NetconfITTest extends AbstractNetconfConfigTest { NetconfMessage response = netconfClient.sendMessage(getConfig); - assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity1")); - assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity2")); - assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity2")); - assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity1")); + assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity1")); + assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity2")); + assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity2")); + assertThat(XmlUtil.toString(response.getDocument()), JUnitMatchers.containsString("prefix:test-identity1")); } catch (Exception e) { fail(Throwables.getStackTraceAsString(e)); diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java index 66603fb6c2..ac200a0aa6 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlElement.java @@ -10,9 +10,17 @@ package org.opendaylight.controller.netconf.util.xml; import com.google.common.base.Optional; import com.google.common.base.Predicate; +import com.google.common.base.Strings; import com.google.common.collect.Collections2; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Nullable; import org.opendaylight.controller.netconf.api.NetconfDocumentedException; import org.opendaylight.controller.netconf.util.exception.MissingNameSpaceException; import org.opendaylight.controller.netconf.util.exception.UnexpectedElementException; @@ -28,14 +36,6 @@ import org.w3c.dom.NodeList; import org.w3c.dom.Text; import org.xml.sax.SAXException; -import javax.annotation.Nullable; -import java.io.IOException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - public final class XmlElement { private final Element element; @@ -111,7 +111,7 @@ public final class XmlElement { public void checkNamespaceAttribute(String expectedNamespace) throws UnexpectedNamespaceException, MissingNameSpaceException { if (!getNamespaceAttribute().equals(expectedNamespace)) { - throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s for element %s, should be %s", + throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s should be %s", getNamespaceAttribute(), expectedNamespace), NetconfDocumentedException.ErrorType.application, @@ -123,7 +123,7 @@ public final class XmlElement { public void checkNamespace(String expectedNamespace) throws UnexpectedNamespaceException, MissingNameSpaceException { if (!getNamespace().equals(expectedNamespace)) { - throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s for element %s, should be %s", + throw new UnexpectedNamespaceException(String.format("Unexpected namespace %s should be %s", getNamespace(), expectedNamespace), NetconfDocumentedException.ErrorType.application, @@ -320,23 +320,22 @@ public final class XmlElement { } public String getTextContent() throws NetconfDocumentedException { - Node textChild = element.getFirstChild(); - if (null == textChild){ - throw new NetconfDocumentedException(String.format( "Child node expected, got null for " + getName() + " : " + element), - NetconfDocumentedException.ErrorType.application, - NetconfDocumentedException.ErrorTag.invalid_value, - NetconfDocumentedException.ErrorSeverity.error); + NodeList childNodes = element.getChildNodes(); + if (childNodes.getLength() == 0) { + return ""; } - if (!(textChild instanceof Text)){ - throw new NetconfDocumentedException(String.format(getName() + " should contain text." + - Text.class.getName() + " expected, got " + textChild), - NetconfDocumentedException.ErrorType.application, - NetconfDocumentedException.ErrorTag.invalid_value, - NetconfDocumentedException.ErrorSeverity.error); + for(int i = 0; i < childNodes.getLength(); i++) { + Node textChild = childNodes.item(i); + if (textChild instanceof Text) { + String content = textChild.getTextContent(); + return content.trim(); + } } - String content = textChild.getTextContent(); - // Trim needed - return content.trim(); + throw new NetconfDocumentedException(getName() + " should contain text.", + NetconfDocumentedException.ErrorType.application, + NetconfDocumentedException.ErrorTag.invalid_value, + NetconfDocumentedException.ErrorSeverity.error + ); } public String getNamespaceAttribute() throws MissingNameSpaceException { @@ -351,15 +350,24 @@ public final class XmlElement { return attribute; } - public String getNamespace() throws MissingNameSpaceException { + public Optional getNamespaceOptionally() { String namespaceURI = element.getNamespaceURI(); - if (namespaceURI == null || namespaceURI.equals("")){ + if (Strings.isNullOrEmpty(namespaceURI)) { + return Optional.absent(); + } else { + return Optional.of(namespaceURI); + } + } + + public String getNamespace() throws MissingNameSpaceException { + Optional namespaceURI = getNamespaceOptionally(); + if (namespaceURI.isPresent() == false){ throw new MissingNameSpaceException(String.format("No namespace defined for %s", this), NetconfDocumentedException.ErrorType.application, NetconfDocumentedException.ErrorTag.operation_failed, NetconfDocumentedException.ErrorSeverity.error); } - return namespaceURI; + return namespaceURI.get(); } @Override diff --git a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java index 1f81117ca3..b2b202b69e 100644 --- a/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java +++ b/opendaylight/netconf/netconf-util/src/main/java/org/opendaylight/controller/netconf/util/xml/XmlUtil.java @@ -10,11 +10,12 @@ package org.opendaylight.controller.netconf.util.xml; import com.google.common.base.Charsets; import com.google.common.base.Optional; -import org.w3c.dom.Document; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; - +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; import javax.xml.XMLConstants; import javax.xml.namespace.QName; import javax.xml.parsers.DocumentBuilder; @@ -32,17 +33,15 @@ import javax.xml.validation.Schema; import javax.xml.validation.SchemaFactory; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathExpressionException; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; public final class XmlUtil { public static final String XMLNS_ATTRIBUTE_KEY = "xmlns"; - private static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; + public static final String XMLNS_URI = "http://www.w3.org/2000/xmlns/"; private static final DocumentBuilderFactory BUILDERFACTORY; static { @@ -118,8 +117,14 @@ public final class XmlUtil { return typeElement; } - public static Element createPrefixedTextElement(Document document, String qName, String prefix, String content, Optional namespace) { - return createTextElement(document, qName, createPrefixedValue(prefix, content), namespace); + public static Element createTextElementWithNamespacedContent(Document document, String qName, String prefix, + String namespace, String contentWithoutPrefix) { + + String content = createPrefixedValue(XmlNetconfConstants.PREFIX, contentWithoutPrefix); + Element element = createTextElement(document, qName, content, Optional.absent()); + String prefixedNamespaceAttr = createPrefixedValue(XMLNS_ATTRIBUTE_KEY, prefix); + element.setAttributeNS(XMLNS_URI, prefixedNamespaceAttr, namespace); + return element; } public static String createPrefixedValue(String prefix, String value) { -- 2.36.6