【发布时间】:2019-03-23 04:56:44
【问题描述】:
我必须修改传入的 SOAP XML 消息以将名称空间添加到其中一个元素,以便反序列化能够正常工作。但是,当我将 xmlns 属性添加到正确的元素时,当我尝试通过流将 xml 加载到 XmlWriter 时出现错误(我需要在 IClientMessageInspector 实现中这样做以替换消息回复)。
The prefix '' cannot be redefined from '' to 'http://www.example.com' within the same start element tag.
我有一个解决方法,即在修改属性后,我从它自己的 OuterXML 重新加载整个 XML 文档。这出于某种原因,但让我认为必须有一个“正确”的方法来做到这一点。
这是一个演示问题和我当前解决方案的示例测试:
[Test]
public void XmlNamespaceTest()
{
var originalXmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?><TestElement><Child>thing</Child></TestElement>";
var desiredXmlString = "<?xml version=\"1.0\" encoding=\"utf-8\"?><TestElement xmlns=\"http://www.example.com\"><Child>thing</Child></TestElement>";
var doc = new XmlDocument();
doc.LoadXml(originalXmlString);
Assert.That(originalXmlString, Is.EqualTo(doc.OuterXml));
// Write this document via an XMLWriter
var ms = new MemoryStream();
var xmlWriter = XmlWriter.Create(ms);
doc.WriteTo(xmlWriter);
xmlWriter.Flush();
ms.Position = 0;
StreamReader sr = new StreamReader(ms);
var originalXmlViaXmlWriter = sr.ReadToEnd();
Assert.That(originalXmlString, Is.EqualTo(originalXmlViaXmlWriter));
// Add the namespace to the element
((XmlElement)doc.GetElementsByTagName("TestElement").Item(0))?.SetAttribute("xmlns", "http://www.example.com");
Assert.That(desiredXmlString, Is.EqualTo(doc.OuterXml));
// Now attempt to write this modified xml via an XMLWriter
ms.SetLength(0);
xmlWriter = XmlWriter.Create(ms);
//Uncomment line below to fix the error.
//doc.LoadXml(doc.OuterXml);
doc.WriteTo(xmlWriter);
xmlWriter.Flush();
ms.Position = 0;
sr = new StreamReader(ms);
var modifedXmlViaXmlWriter = sr.ReadToEnd();
Assert.That(desiredXmlString, Is.EqualTo(modifedXmlViaXmlWriter));
}
【问题讨论】:
-
如果所有元素都使用相同的命名空间,您可以为整个 XML 文档设置一个默认命名空间,而无需为每个节点设置命名空间。编辑:我认为这与
soap无关。考虑删除该标签,以便为您的问题提供更好的受众。 -
我刚查了一下,XmlNode的NamespaceUri属性是只读的;所以我认为最简单的方法可能是使用
CreateDocumentFragment()创建一个新节点,将其InnerXml 设置为oldNode.InnerXml.Replace ("<TestElement>", "<TestElement xmlns=\"http://www.example.com\">"),然后在oldNode 的父节点上调用ReplaceChild。
标签: c# soap namespaces xmldocument