【问题标题】:Correct way to add a namespace to an element using XmlDocument使用 XmlDocument 向元素添加命名空间的正确方法
【发布时间】: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 ("&lt;TestElement&gt;", "&lt;TestElement xmlns=\"http://www.example.com\"&gt;"),然后在oldNode 的父节点上调用ReplaceChild

标签: c# soap namespaces xmldocument


【解决方案1】:

根据this,您不能更改XmlDocument 中的元素命名空间。这也是@LocEngineer 在他的评论中发现的。引用的文章提到,这样做的唯一方法是保存并重新加载XmlDocument,这正是您正在做的事情。

如果您可以改用XDoxument,这是可能的。请参阅this 答案以获取解决方案。

【讨论】:

    猜你喜欢
    • 2010-09-24
    • 1970-01-01
    • 2014-01-06
    • 2011-11-17
    • 2014-06-10
    • 1970-01-01
    • 2010-09-13
    • 2012-08-16
    • 1970-01-01
    相关资源
    最近更新 更多