如何使用.NET XML API移除xmlns属性

8

XmlElement.Attributes.Remove* 方法适用于任意属性,可以将被删除的属性从 XmlDocument.OuterXml 属性中移除。但是 Xmlns 属性不同。以下是一个示例:

XmlDocument doc = new XmlDocument();
doc.InnerXml = @"<Element1 attr1=""value1"" xmlns=""http://mynamespace.com/"" attr2=""value2""/>";
doc.DocumentElement.Attributes.RemoveNamedItem("attr2");
Console.WriteLine("xmlns attr before removal={0}", doc.DocumentElement.Attributes["xmlns"]);
doc.DocumentElement.Attributes.RemoveNamedItem("xmlns");
Console.WriteLine("xmlns attr after removal={0}", doc.DocumentElement.Attributes["xmlns"]);

生成的输出为:
xmlns attr before removal=System.Xml.XmlAttribute
xmlns attr after removal=
<Element1 attr1="value1" xmlns="http://mynamespace.com/" />

这个属性似乎已经从属性集合中移除了,但它没有从XmlDocument.OuterXml中删除。 我猜这是因为这个属性的特殊含义所致。

问题在于如何使用.NET XML API删除xmlns属性。 显然,我可以从字符串表示中直接删除该属性,但我想知道是否可以使用API做到同样的事情。

@编辑:我在谈论.NET 2.0。


我刚遇到了这个问题。不错的发现! - Hasani Blackwell
9个回答

3
非常感谢Ali Shah,这个帖子完美地解决了我的问题!以下是C#转换代码:
var dom = new XmlDocument();
        dom.Load("C:/ExampleFITrade.xml));
        var loaded = new XDocument();
        if (dom.DocumentElement != null)
            if( dom.DocumentElement.NamespaceURI != String.Empty)
            {
                dom.LoadXml(dom.OuterXml.Replace(dom.DocumentElement.NamespaceURI, ""));
                dom.DocumentElement.RemoveAllAttributes();
                loaded = XDocument.Parse(dom.OuterXml);
            }

2

我看到了这个帖子中的各种选项,并想出了自己的解决方案,用于删除XML中的xmlns属性。这个方案可以正常工作,没有问题:

'Remove the Equifax / Transunian / Experian root node attribute that have xmlns and load xml without xmlns attributes.
If objXMLDom.DocumentElement.NamespaceURI <> String.Empty Then
  objXMLDom.LoadXml(objXMLDom.OuterXml.Replace(objXMLDom.DocumentElement.NamespaceURI, ""))
  objXMLDom.DocumentElement.RemoveAllAttributes()
  ResponseXML = objXMLDom.OuterXml
End If

从xml中删除xmlns无需进行其他操作。


2

.NET DOM API不支持修改元素的命名空间,这正是您尝试做的。因此,为了解决您的问题,您必须以某种方式构建一个新文档。您可以使用相同的.NET DOM API创建一个新元素,而不指定其命名空间。或者,您可以创建一个XSLT样式表,将原始的“有命名空间”的文档转换为一个新文档,在其中元素将不会带命名空间。


我不确定,但只要没有肯定的答案,我相信它是真的。 - axk

2
“这个不是应该移除命名空间吗?”
XmlNamespaceManager mgr = new XmlNamespaceManager("xmlnametable");
mgr.RemoveNamespace("prefix", "uri");

无论如何,这里有一个离题的话题,来自System.Xml.Linq命名空间(.Net 3.0)的XElement、XDocument和XNameSpace类比旧的XmlDocument模型更好。试试吧,我已经上瘾了。


感谢您的建议。我一定会尝试的。 - axk

1
public static string RemoveXmlns(string xml)
{
    //Prepare a reader
    StringReader stringReader = new StringReader(xml);
    XmlTextReader xmlReader = new XmlTextReader(stringReader);
    xmlReader.Namespaces = false; //A trick to handle special xmlns attributes as regular
    //Build DOM
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.Load(xmlReader);
    //Do the job
    xmlDocument.DocumentElement.RemoveAttribute("xmlns"); 
    //Prepare a writer
    StringWriter stringWriter = new StringWriter();
    XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);
    //Optional: Make an output nice ;)
    xmlWriter.Formatting = Formatting.Indented;
    xmlWriter.IndentChar = ' ';
    xmlWriter.Indentation = 2;
    //Build output
    xmlDocument.Save(xmlWriter);
    return stringWriter.ToString();
}

2
提供您的答案时,附上一小段叙述性描述会更有帮助。 - Rob

0

这是我的VB.NET解决方案,大家看看吧!

   Dim pathXmlTransformado As String = "C:\Fisconet4\process\11790941000192\2015\3\28\38387-1\38387_transformado.xml"
    Dim nfeXML As New XmlDocument
    Dim loaded As New XDocument

    nfeXML.Load(pathXmlTransformado)

    nfeXML.LoadXml(nfeXML.OuterXml.Replace(nfeXML.DocumentElement.NamespaceURI, ""))
    nfeXML.DocumentElement.RemoveAllAttributes()

    Dim dhCont As XmlNode = nfeXML.CreateElement("dhCont")
    Dim xJust As XmlNode = nfeXML.CreateElement("xJust")
    dhCont.InnerXml = 123
    xJust.InnerXml = 123777

    nfeXML.GetElementsByTagName("ide")(0).AppendChild(dhCont)
    nfeXML.GetElementsByTagName("ide")(0).AppendChild(xJust)

    nfeXML.Save("C:\Fisconet4\process\11790941000192\2015\3\28\38387-1\teste.xml")

0
我们可以将XML转换为字符串,从该字符串中删除xmlns,然后使用此字符串创建另一个XmlDocument,该文档将不具有命名空间。

0

是的,因为它是一个元素名称,你不能明确地删除它。使用XmlTextWriter的WriteStartElement和WirteStartAttribute,并用空格替换属性可能会完成任务。

我正在检查它。稍后更新。


0

我已经尝试过这个,但是还没有找到如何使用这个类来删除命名空间。 - axk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接