.Net默认情况下,使用前缀将名称空间添加到XML文档 [英] .Net Add namespace to XML document as default and with a prefix

查看:55
本文介绍了.Net默认情况下,使用前缀将名称空间添加到XML文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用XMLSerializer在vb.net中创建类oXML的序列化的XML字符串时,如下所示:

When using XMLSerializer to create an XML string of a serialization of a class oXML in vb.net as follows:

Dim x As New Xml.Serialization.XmlSerializer(oXML.GetType, "urn:oecd:blah:blah")
Dim xmlns = New XmlSerializerNamespaces()

xmlns.Add(String.Empty, "urn:oecd:blah:blah")
xmlns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance")
xmlns.Add("sfa", "urn:oecd:blah:blah1")
xmlns.Add("iso", "urn:oecd:blah:blah2")
xmlns.Add("ftc", "urn:oecd:blah:blah")

Dim sw As New IO.StringWriter()
x.Serialize(sw, oXML, xmlns)

您将注意到,我已经重复添加了名称空间"urn:oecd:blah:blah"作为xmlns对象上的空默认"名称空间以及x As New Xml.Serialization.XmlSerializer的定义.

You will notice that I have repeated the addition of namespace "urn:oecd:blah:blah" as both an empty "default" namespace on the xmlns object and also in the definition of x As New Xml.Serialization.XmlSerializer.

问题在于,仅使用ftc前缀呈现此特定名称空间,而未显示默认名称空间.如果我注释掉ftc名称空间的添加,然后再次运行它,那么将正确呈现默认名称空间.有没有办法告诉序列化程序此名称空间用作默认名称,并且还带有ftc前缀?我假设这是因为命名空间被使用了两次,既是默认名称,又带有前缀,它会忽略它?

The problem is that this particular namespace only ever gets rendered with a prefix of ftc and the default is not shown. If I comment out the addition of the ftc namespace, and run it again, then a default namespace is rendered correctly. Is there a way to tell the serializer that this namespace is used as default and also with a prefix of ftc? I am assuming it is because the namespace is used twice, both as default and also with a prefix that it is ignoring it?

推荐答案

XmlSerializer 在传递带有两个前缀的 XmlSerializerNamespaces 表示相同命名空间的情况下,没有定义的行为.它可以选择任何一个前缀,并且结果在语义上是相同的.此外,从参考源中获取该类的信息似乎名称空间存储在哈希表中,因此它们的顺序是不可预测的.但是,由于XML的两种方式都具有相同的含义,所以您要做的最简单的事情就是不用担心它.

XmlSerializer has no defined behavior in the case of passing an XmlSerializerNamespaces with two prefixes for identical namespaces. It could choose either prefix and the result would be semantically identical. Further, from the reference source for the class it appears the namespaces are stored in a hash table so their order is unpredictable. But since the XML would have the same meaning either way, the simplest thing for you to do is to not worry about it.

如果出于某种原因必须在XML中具有重复的名称空间,并且必须使用默认前缀优先于该名称空间中元素的等效命名前缀,则您可以序列化为 XDocument ,然后手动添加丢失的重复项:

If for some reason you must have duplicated namespaces in your XML, and must use the default prefix in preference to an equivalent named prefix for elements in that namespace, you could serialize to an XDocument then add the missing duplicates manually:

Public Module XObjectExtensions
    <System.Runtime.CompilerServices.Extension> 
    Public Function SerializeToXDocument(Of T)(obj As T, serializer As XmlSerializer, ns As XmlSerializerNamespaces) As XDocument
        Dim doc = New XDocument()
        Using writer = doc.CreateWriter()
            serializer = If(serializer, New XmlSerializer(obj.GetType()))
            serializer.Serialize(writer, obj, ns)
        End Using
        If doc.Root IsNot Nothing AndAlso ns IsNot Nothing Then
            ' Add missing namespaces
            For Each name In ns.ToArray().Except(doc.Root.Attributes().Where(Function(a) a.IsNamespaceDeclaration).Select((Function(a) New XmlQualifiedName(a.Name.LocalName, a.Value))))
                doc.Root.Add(New XAttribute("xmlns" + (If(String.IsNullOrEmpty(name.Name), String.Empty, ":" + name.Name)), name.Namespace))
            Next
        End If

        Return doc
    End Function
End Module

然后像这样使用它:

        Dim xDoc = oXML.SerializeToXDocument(x, xmlns)

        Dim xml2 as String
        Using sw = New IO.StringWriter()
            xDoc.Save(sw)
            xml2 = sw.ToString()
        End Using

示例 dotnetfiddle .

现在,在您的情况下,省略了默认名称空间,而使用了重复的带前缀的名称空间.如果出于某种原因 XmlSerializer 选择了相反的操作(并且没有选择它将记录在文档中),那么在根文档名称空间列表的末尾添加缺少的命名名称空间将导致所有元素被写入带有命名前缀.那是因为事实证明,编写 XElement 时, XDocument保存删除节点前缀a>,然后将默认前缀移到属性列表的 end 而不是开头.

Now, in your case the default namespace was omitted in favor of a duplicated prefixed namespace. If for some reason XmlSerializer chose to do the opposite (and it's not documented which it will choose), then adding the missing named namespace at the end of the root document's namespace list would cause all elements to be written with the named prefix. That's because it turns out that, when writing an XElement, name/namespace pairs are pushed onto a stack during serialization and so the lattermost is used. To work around this, you could adapt the code from XDocument Save Removing Node Prefixes and move the default prefix to the end of the attribute list rather than the beginning.

这篇关于.Net默认情况下,使用前缀将名称空间添加到XML文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆