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

时间:2015-08-11 15:42:15

标签: 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);

扩展方法

    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);
            }
        }
    }

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

<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>

如何完全删除命名空间?

3 个答案:

答案 0 :(得分:3)

最简单的方法是&#39;后处理&#39; 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();

另一个选项(因为你不能修改源类XML属性)是为XmlWriter实现一个忽略所有命名空间的装饰器,但它是一个非常大的类,所以#&# 39; d是很多样板代理。

答案 1 :(得分:0)

这是另一种解决方案:

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);

}

答案 2 :(得分:-2)

我有时会使用RegEx或XML Linq

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string input =
                "<q1:InventoryFeed xmlns:q1=\"http://thecompany.com/\">\n" +
                    "<q1:InventoryHeader>\n" +
                        "<q1:version>1.4</q1:version>\n" +
                    "</q1:InventoryHeader>\n" +
                    "<q1:inventory>v" +
                        "<q1:sku>WMSkuCap0180</q1:sku>\n" +
                        "<q1:quantity>\n" +
                            "<q1:unit>EACH</q1:unit>\n" +
                            "<q1:amount>3</q1:amount>\n" +
                        "</q1:quantity>\n" +
                        "<q1:fulfillmentLagTime>1</q1:fulfillmentLagTime>\n" +
                    "</q1:inventory>\n" +
                "</q1:InventoryFeed>\n";

            string pattern1 = @"<[^/][^:]+:";
            string output = Regex.Replace(input, pattern1, "<");
            string pattern2 = @"</[^:]+:";
            output = Regex.Replace(output, pattern2, "</");

            //using xml linq
            XElement element = XElement.Parse(input);
            foreach (var node in element.DescendantNodesAndSelf())
            {
                if (node.NodeType == XmlNodeType.Element)
                {
                    ((XElement)node).Name = ((XElement)node).Name.LocalName;
                }
            }
        }
    }
}
​