[英]C# XmlSerializer xmlns in child element matching parent
我正在使用XmlSerializer创建一个XML文档,用于eBay的大型商家服务。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<BulkDataExchangeRequests xmlns="urn:ebay:apis:eBLBaseComponents">
<Header>
<SiteID>0</SiteID>
<Version>775</Version>
</Header>
<AddFixedPriceItemRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<Version>775</Version>
<Item>
<AutoPay>false</AutoPay>
<BuyerProtection>ItemIneligible</BuyerProtection>
<BuyItNowPrice currencyID="USD">0.0</BuyItNowPrice>
<Country>US</Country>
<Currency>USD</Currency>
<Description>test</Description>
<GiftIcon>0</GiftIcon>
</Item>
</AddFixedPriceItemRequest>
</BulkDataExchangeRequests>
我遇到的问题是让序列化程序生成的AddFixedPriceItemRequest实际包含像BulkDataExchangeRequests元素那样的xmlns。 看来这是一项要求。 我使用以下代码生成批量代码:
writer.WriteStartElement("BulkDataExchangeRequests", "urn:ebay:apis:eBLBaseComponents");
我创建一个序列化器。
serializer = new XmlSerializer(typeof(AddFixedPriceItemRequestType));//, "urn:ebay:apis:eBLBaseComponents");
并使用命名空间进行序列化
request = new AddFixedPriceItemRequestType()
{
//populate data.
};
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
namespaces.Add("", "urn:ebay:apis:eBLBaseComponents");
serializer.Serialize(writer, request, namespaces);
这是具有xml属性的类型:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "2.0.50727.5420")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:ebay:apis:eBLBaseComponents",TypeName="AddFixedPriceItemRequest")]
public partial class AddFixedPriceItemRequestType : AbstractRequestType {
//filled in class
}
我的输出最终像这样:
<AddFixedPriceItemRequest xmlns="">
<ErrorLanguage xmlns="urn:ebay:apis:eBLBaseComponents">en_US</ErrorLanguage>
<Version xmlns="urn:ebay:apis:eBLBaseComponents">837</Version>
<Item p4:type="Item" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance" xmlns="urn:ebay:apis:eBLBaseComponents">
有人可以帮忙解决如何通过序列化程序获取addfixedpriceitemrequest设置的xmlns以匹配批量xmlns。 或推荐另一种方法。 我试图避免使用createelement / writeelement写入每个属性。
这对我行得通
ItemType itemType = new ItemType()
{
//populate data.
};
ApiCall apiCall = new AddItemCall() { Item = itemType };
AddItemRequestType addFixedPriceItemRequestType = ((AddItemCall)apiCall).ApiRequest;
XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] {
new XmlQualifiedName(string.Empty, "urn:ebay:apis:eBLBaseComponents")});
XmlSerializer xmlSerializer = new XmlSerializer(
addFixedPriceItemRequestType.GetType(), "urn:ebay:apis:eBLBaseComponents");
MemoryStream memoryStream = new MemoryStream();
xmlSerializer.Serialize(memoryStream, addFixedPriceItemRequestType , namespaces);
memoryStream.Seek((long)0, SeekOrigin.Begin);
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.Load(memoryStream);
memoryStream.Close();
string addItemRequestTypeXML = xmlDocument.OuterXml;
输出将是:
<AddItemRequestType xmlns="urn:ebay:apis:eBLBaseComponents">
<Item>
<ApplicationData></ApplicationData>
<AutoPay>false</AutoPay>
<CategoryMappingAllowed>true</CategoryMappingAllowed>
<Country>US</Country>
<Currency>EUR</Currency>
<Description>
....
<AddItemRequestType>
问题很可能出在XmlTypeAttribute
-看来您将类用作顶级容器-应该使用XmlRootAttribute
。 这样,您将把urn:ebay:apis:eBLBaseComponents
放置在正确的位置。
样品:
void Main()
{
var t = new A {FieldOfB = new B {C = 5}};
var serializer = new XmlSerializer(typeof(A));
using (var writer = new StringWriter())
{
serializer.Serialize(writer, t);
writer.ToString().Dump();
}
}
与此类定义一起使用时:
[System.Xml.Serialization.XmlTypeAttribute(Namespace="urn:ebay:apis:eBLBaseComponents")]
public class A
{
public B FieldOfB {get;set;}
}
public class B
{
public int C {get;set;}
}
产生以下结果:
<?xml version="1.0" encoding="utf-16"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<FieldOfB xmlns="urn:ebay:apis:eBLBaseComponents">
<C>5</C>
</FieldOfB>
</A>
并且如果您修复了该属性:
[System.Xml.Serialization.XmlRootAttribute(Namespace="urn:ebay:apis:eBLBaseComponents")]
public class A
{
public B FieldOfB {get;set;}
}
public class B
{
public int C {get;set;}
}
你得到这个:
<?xml version="1.0" encoding="utf-16"?>
<A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:ebay:apis:eBLBaseComponents">
<FieldOfB>
<C>5</C>
</FieldOfB>
</A>
eBay仅需要在Trade API中设置名称空间。 一种解决方案是删除BulkDataExchange对象中的名称空间设置,并仅在Trade API对象中添加名称空间设置。 这不是标准的XML格式,但是eBay仅接受此格式。
就您而言,这可能对eBay有用:
writer.WriteStartElement("BulkDataExchangeRequests", "");
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.