我给了一个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>
如何完全删除命名空间?
答案 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;
}
}
}
}
}