从 xml 中删除 q1 和所有命名空间

Bra*_*ard 7 c# xml namespaces

我得到了一个 xsd 生成的 C# POCO 对象,我需要将其转换为 xml。然而,预期的有效载荷与我得到的 xsds 不匹配。具体来说,我需要省略声明并从 xml 对象中删除所有命名空间,以便相关公司接受 API 请求。

问题

给定一个类型为 T 的对象,我想在没有声明和命名空间的情况下对其进行序列化。

我已经摆脱了大部分,但由于某种原因,q1 已添加到每个元素中。我如何删除它?

试图

经过一些研究,我看到一些帖子提供了一个解决方案,该解决方案创建一个空的 xml 序列化器命名空间并使用该对象调用序列化器。那只让我成功了一半。

用法

        var ns = new XmlSerializerNamespaces();
        ns.Add("", "");
        var body = payload.SerializeObject(false, true, ns);
Run Code Online (Sandbox Code Playgroud)

扩展方法

    public static string SerializeObject<T>(this T obj, bool indented, bool omitDeclaration, XmlSerializerNamespaces ns)
    {
        var utf8NoBom = new UTF8Encoding(false);
        var settings = new XmlWriterSettings
        {
            OmitXmlDeclaration = omitDeclaration,
            Indent = indented,
            Encoding = utf8NoBom
        };
        using (MemoryStream ms = new MemoryStream())
        {
            using (var xmlWriter = XmlWriter.Create(ms, settings))
            {
                XmlSerializer xmlSer = new XmlSerializer(typeof(T));
                xmlSer.Serialize(xmlWriter, obj, ns);
                byte[] bytes = ms.ToArray();
                return utf8NoBom.GetString(bytes);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

不幸的是,结果看起来像这样。

<q1:InventoryFeed xmlns:q1=\"http://thecompany.com/\">
    <q1:InventoryHeader>
        <q1:version>1.4</q1:version>
    </q1:InventoryHeader>
    <q1:inventory>
        <q1:sku>WMSkuCap0180</q1:sku>
        <q1:quantity>
            <q1:unit>EACH</q1:unit>
            <q1:amount>3</q1:amount>
        </q1:quantity>
        <q1:fulfillmentLagTime>1</q1:fulfillmentLagTime>
    </q1:inventory>
</q1:InventoryFeed>
Run Code Online (Sandbox Code Playgroud)

如何完全删除命名空间?

Cha*_*ger 7

最简单的方法是对 XML 进行“后处理”:

var doc = XDocument.Parse(xml);

doc.Descendants().Attributes().Where(a => a.IsNamespaceDeclaration).Remove();

foreach (var element in doc.Descendants())
{
    element.Name = element.Name.LocalName;
}

var xmlWithoutNamespaces = doc.ToString();
Run Code Online (Sandbox Code Playgroud)

另一种选择(因为你不能修改源类 XML 属性)是实现一个装饰器XmlWriter,忽略所有命名空间,但它是一个相当大的类,所以会有很多样板委托。


小智 7

这是另一个解决方案:

XmlWriterSettings settings = new XmlWriterSettings();
//If you wish Encoding
settings.Encoding = Encoding.GetEncoding("ISO-8859-1");

using (XmlWriter xmlWriter = XmlWriter.Create(tempFilePath, settings))
{
     var ns = new XmlSerializerNamespaces();
     ns.Add("", "http://thecompany.com");
     XmlSerializer s = new XmlSerializer(YOUROBJECT.GetType(), "http://thecompany.com");    
     s.Serialize(xmlWriter, YOUROBJECT, ns);

}
Run Code Online (Sandbox Code Playgroud)