jjzjj

c# XML 序列化 : Order of namespace declarations

coder 2024-06-24 原文

我有一个非常奇怪的情况。我像这样序列化我的命名空间:

var namespaces = new XmlSerializerNamespaces();
namespaces.Add("xsd", "http://www.w3.org/2001/XMLSchema");
namespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");

serializer.Serialize(writer, config, namespaces);

在我的机器上,我得到以下 xml(我刚刚添加了换行符的一行):

<SystemConfiguration 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns="http://www.schaeffler.com/sara/systemconfiguration/">

在 buildserver 上我得到了同样的软件:

<SystemConfiguration 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
      xmlns="http://www.schaeffler.com/sara/systemconfiguration/">

您会看到 xsd 和 xsi 的顺序被调换了。我检查了序列化程序的实现,发现顺序是用哈希表确定的,并且没有 XmlSerializerNamespaces 接口(interface)来为命名空间实现我自己的序列化程序。

这是XmlSerializationWriter中的方法:

protected void WriteNamespaceDeclarations(XmlSerializerNamespaces xmlns)
    {
      if (xmlns != null)
      {
        foreach (DictionaryEntry dictionaryEntry in xmlns.Namespaces)
        {
          string localName = (string) dictionaryEntry.Key;
          string ns = (string) dictionaryEntry.Value;
          if (this.namespaces != null)
          {
            string str = this.namespaces.Namespaces[(object) localName] as string;
            if (str != null && str != ns)
              throw new InvalidOperationException(Res.GetString("XmlDuplicateNs", (object) localName, (object) ns));
          }
          string str1 = ns == null || ns.Length == 0 ? (string) null : this.Writer.LookupPrefix(ns);
          if (str1 == null || str1 != localName)
            this.WriteAttribute("xmlns", localName, (string) null, ns);
        }
      }
      this.namespaces = (XmlSerializerNamespaces) null;
    }

什么会导致 hashmap 中命名空间的不同顺序?

最佳答案

我已经实现了一个自定义 XmlWriter,它确保根元素中的 namespace 在写出之前已排序:

/// <summary>
/// XmlWriter that ensures the namespace declarations in the root element are always sorted.
/// </summary>
class SortedNamespaceXmlWriter : XmlWriter
{
    private readonly XmlWriter _baseWriter;
    private readonly List<(string prefix, string uri)> _namespaces = new List<(string prefix, string uri)>();
    private int _elementIndex;
    private string _nsPrefix;
    private bool _inXmlNsAttribute;


    public SortedNamespaceXmlWriter(XmlWriter baseWriter) => _baseWriter = baseWriter;


    public override void WriteStartElement(string prefix, string localName, string ns)
    {
        _elementIndex++;
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteStartElement(prefix, localName, ns);
    }

    public override void WriteStartAttribute(string prefix, string localName, string ns)
    {
        if (prefix == "xmlns")
        {
            _inXmlNsAttribute = true;
            _nsPrefix = localName;
        }
        else
        {
            FlushRootElementAttributesIfNeeded();
            _baseWriter.WriteStartAttribute(prefix, localName, ns);
        }
    }

    public override void WriteEndAttribute()
    {
        if (_inXmlNsAttribute)
            _inXmlNsAttribute = false;
        else
            _baseWriter.WriteEndAttribute();
    }

    public override void WriteString(string text)
    {
        if (_inXmlNsAttribute)
            _namespaces.Add((_nsPrefix, text));
        else
            _baseWriter.WriteString(text);
    }

    private void FlushRootElementAttributesIfNeeded()
    {
        if (_elementIndex != 1 || _namespaces.Count == 0)
            return;

        _namespaces.Sort((a, b) => StringComparer.Ordinal.Compare(a.prefix, b.prefix));

        foreach (var (prefix, uri) in _namespaces)
        {
            _baseWriter.WriteStartAttribute("xmlns", prefix, null);
            _baseWriter.WriteString(uri);
            _baseWriter.WriteEndAttribute();
        }

        _namespaces.Clear();
    }


    public override WriteState WriteState => _baseWriter.WriteState;

    public override void Flush() => _baseWriter.Flush();

    public override string LookupPrefix(string ns) => _baseWriter.LookupPrefix(ns);

    public override void WriteBase64(byte[] buffer, int index, int count)
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteBase64(buffer, index, count);
    }

    public override void WriteCData(string text)
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteCData(text);
    }

    public override void WriteCharEntity(char ch)
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteCharEntity(ch);
    }

    public override void WriteChars(char[] buffer, int index, int count)
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteChars(buffer, index, count);
    }

    public override void WriteComment(string text)
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteComment(text);
    }

    public override void WriteDocType(string name, string pubid, string sysid, string subset) => _baseWriter.WriteDocType(name, pubid, sysid, subset);

    public override void WriteEndDocument() => _baseWriter.WriteEndDocument();

    public override void WriteEndElement()
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteEndElement();
    }

    public override void WriteEntityRef(string name)
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteEntityRef(name);
    }

    public override void WriteFullEndElement()
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteFullEndElement();
    }

    public override void WriteProcessingInstruction(string name, string text)
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteProcessingInstruction(name, text);
    }

    public override void WriteRaw(char[] buffer, int index, int count)
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteRaw(buffer, index, count);
    }

    public override void WriteRaw(string data)
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteRaw(data);
    }

    public override void WriteStartDocument() => _baseWriter.WriteStartDocument();

    public override void WriteStartDocument(bool standalone) => _baseWriter.WriteStartDocument();

    public override void WriteSurrogateCharEntity(char lowChar, char highChar)
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteSurrogateCharEntity(lowChar, highChar);
    }

    public override void WriteWhitespace(string ws)
    {
        FlushRootElementAttributesIfNeeded();
        _baseWriter.WriteWhitespace(ws);
    }
}

关于c# XML 序列化 : Order of namespace declarations,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20701750/

有关c# XML 序列化 : Order of namespace declarations的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby - 是否有用于序列化和反序列化各种格式的对象层次结构的模式? - 2

    给定一个复杂的对象层次结构,幸运的是它不包含循环引用,我如何实现支持各种格式的序列化?我不是来讨论实际实现的。相反,我正在寻找可能会派上用场的设计模式提示。更准确地说:我正在使用Ruby,我想解析XML和JSON数据以构建复杂的对象层次结构。此外,应该可以将该层次结构序列化为JSON、XML和可能的HTML。我可以为此使用Builder模式吗?在任何提到的情况下,我都有某种结构化数据-无论是在内存中还是文本中-我想用它来构建其他东西。我认为将序列化逻辑与实际业务逻辑分开会很好,这样我以后就可以轻松支持多种XML格式。 最佳答案 我最

  3. ruby - 在 Ruby 中比较序列 - 2

    假设我必须(小型到中型)阵列:tokens=["aaa","ccc","xxx","bbb","ccc","yyy","zzz"]template=["aaa","bbb","ccc"]如何确定tokens是否以相同的顺序包含template的所有条目?(请注意,在上面的示例中,应忽略第一个“ccc”,从而由于最后一个“ccc”而导致匹配。) 最佳答案 这适用于您的示例数据。tokens=["aaa","ccc","xxx","bbb","ccc","yyy","zzz"]template=["aaa","bbb","ccc"]po

  4. ruby-on-rails - carrierwave:在序列化动态属性上安装 uploader - 2

    首先,我使用的是rails3.1.3和来自master的carrierwavegithub仓库的分支。我使用after_init钩子(Hook)来确定基于属性的字段页面模型实例并为这些字段定义属性访问器将值存储在序列化哈希中(希望它清楚我是什么谈论)。这是我正在做的事情的精简版:classPage省略mount_uploader命令让我可以访问我想要的属性。但是当我安装uploader时出现错误消息说“nil类的未定义新方法”我在源代码中读到有方法read_uploader和扩展模块中的write_uploader。我如何必须覆盖这些来制作mount_uploader命令使用我的“虚拟

  5. ruby-on-rails - 如何在 Rails 3 中禁用 XML 解析 - 2

    我想禁用HTTP参数的自动XML解析。但我发现命令仅适用于Rails2.x,它们都不适用于3.0:config.action_controller.param_parsers.deleteMime::XML(application.rb)ActionController::Base.param_parsers.deleteMime::XMLRails3.0中的等价物是什么? 最佳答案 根据CVE-2013-0156的最新安全公告你可以将它用于Rails3.0。3.1和3.2ActionDispatch::ParamsParser::

  6. ruby - 如何使用 Nokogiri::XML::Builder 生成动态标签? - 2

    我正在遍历数组中的一组标签名称,我想使用构建器打印每个标签名称,而不是求助于“我认为:builder=Nokogiri::XML::Builder.newdo|xml|fortagintagsxml.tag!tag,somevalendend会这样做,但它只是创建名称为“tag”的标签,并将标签变量作为元素的文本值。有人可以帮忙吗?这个看起来应该比较简单,我刚刚在搜索引擎上找不到答案。我可能没有以正确的方式提问。 最佳答案 尝试以下操作。如果我没记错的话,我添加了一个根节点,因为Nokogiri需要一个。builder=Nokogi

  7. ruby - 如何让 Nokogiri 解析并返回 XML 文档? - 2

    这是一些奇怪的例子:#!/usr/bin/rubyrequire'rubygems'require'open-uri'require'nokogiri'print"withoutread:",Nokogiri(open('http://weblog.rubyonrails.org/')).class,"\n"print"withread:",Nokogiri(open('http://weblog.rubyonrails.org/').read).class,"\n"运行此返回:withoutread:Nokogiri::XML::Documentwithread:Nokogiri::

  8. 机器学习——时间序列ARIMA模型(四):自相关函数ACF和偏自相关函数PACF用于判断ARIMA模型中p、q参数取值 - 2

    文章目录1、自相关函数ACF2、偏自相关函数PACF3、ARIMA(p,d,q)的阶数判断4、代码实现1、引入所需依赖2、数据读取与处理3、一阶差分与绘图4、ACF5、PACF1、自相关函数ACF自相关函数反映了同一序列在不同时序的取值之间的相关性。公式:ACF(k)=ρk=Cov(yt,yt−k)Var(yt)ACF(k)=\rho_{k}=\frac{Cov(y_{t},y_{t-k})}{Var(y_{t})}ACF(k)=ρk​=Var(yt​)Cov(yt​,yt−k​)​其中分子用于求协方差矩阵,分母用于计算样本方差。求出的ACF值为[-1,1]。但对于一个平稳的AR模型,求出其滞

  9. ruby-on-rails - Rails 编辑序列化的 JSON 数据 - 2

    我有一个存储JSON数据的列。当它处于编辑状态时,我不知道如何显示它。serialize:value,JSON=f.fields_for:valuedo|ff|.form-group=ff.label:short=ff.text_field:short,class:'form-control'.form-group=ff.label:long=ff.text_field:long,class:'form-control' 最佳答案 代替=f.fields_for:valuedo|ff|请使用以下代码:=f.fields_for:va

  10. ruby - 模式加载时出现 Nokogiri::XML::Schema SyntaxError - 2

    我正在尝试加载SAML协议(protocol)架构(具体来说:https://www.oasis-open.org/committees/download.php/3407/oasis-sstc-saml-schema-protocol-1.1.xsd),但在执行此操作之后:schema=Nokogiri::XML::Schema(File.read('saml11_schema.xsd'))我得到这个输出:Nokogiri::XML::SyntaxErrorException:Element'{http://www.w3.org/2001/XMLSchema}element',att

随机推荐