[英]Serialize object to XML without empty elements and elements with empty children
I need to serialize object into XML request, but the service, I am calling, do not accept empty elements. 我需要将对象序列化为XML请求,但是我正在调用的服务不接受空元素。
I generated contract classes from XSDs and the request structure looks like follows: 我从XSD生成了合同类,请求结构如下所示:
/* Generated contracts - simplified & without XML attributes */
public class Request
{
public Request()
{
filters = new RequestFilters();
properties = new ResultProperties();
}
public RequestFilters filters { get; set; }
public ResultProperties properties { get; set; }
}
public class ResultProperties
{
public ResultProperties()
{
props = new List<string>();
}
public List<string> props { get; set; }
}
public class RequestFilters
{
public RequestFilters()
{
ids = new LongFilter();
names = new StringFilter();
}
public LongFilter ids { get; set; }
public StringFilter names { get; set; }
}
public class LongFilter
{
public LongFilter()
{
values = new List<long>();
}
public List<long> values { get; set; }
}
public class StringFilter
{
public StringFilter()
{
values = new List<string>();
}
public List<string> values { get; set; }
}
For the code generation I've used xsd2code and configured it to exclude empty collections from serialization. 对于代码生成,我使用了xsd2code并将其配置为从序列化中排除空集合。 When creating object
创建对象时
Request request = new Request();
ResultProperties rp = new ResultProperties();
rp.props.Add("foo");
rp.props.Add("bar");
request.properties = rp;
I can serialize it into XML: 我可以将其序列化为XML:
<?xml version="1.0" encoding="utf-16"?>
<Request xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<filters>
<ids />
<names />
</filters>
<properties>
<props>
<string>foo</string>
<string>bar</string>
</props>
</properties>
</Request>
However the backend service complains about empty <ids />
and <names />
elements. 但是后端服务抱怨
<ids />
和<names />
元素为空。
Is there a preferred/any way to exclude those empty elements from serialized XML? 有没有一种首选/任何方法可以从序列化XML中排除那些空元素?
If I manage to exclude <ids />
and <names />
, eventually I would like to get rid of <filters>
element too. 如果我设法排除
<ids />
和<names />
,那么最终我也想摆脱<filters>
元素。 Thanks. 谢谢。
UPDATE: Added relevant part of XSD 更新:添加了XSD的相关部分
<xs:schema>
<xs:element name="Request">
<xs:complexType>
<xs:sequence>
<xs:element name="filters" type="ouext:RequestFilters" minOccurs="0" />
<xs:element name="properties" type="ouext:ResultProperties" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="RequestFilters">
<xs:sequence>
<xs:element name="ids" type="filters:LongFilter" minOccurs="0" />
<xs:element name="names" type="filters:StringFilter" minOccurs="0" />
<xs:sequence>
</xs:complexType>
<xs:complexType name="LongFilter">
<xs:sequence>
<xs:element name="values" type="filters:LongInFilter" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="LongInFilter">
<xs:sequence>
<xs:element name="value" type="xs:long" minOccurs="0" maxOccurs="20000" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="StringFilter">
<xs:sequence>
<xs:element name="values" type="filters:StringInFilter" minOccurs="0" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="StringInFilter">
<xs:sequence>
<xs:element name="value" type="xs:string" minOccurs="0" maxOccurs="20000" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="ResultProperties">
<xs:sequence>
<xs:element name="props" type="filters:StringInFilter" minOccurs="0" maxOccurs="unbounded">
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
UPDATE: Serialization is done as follows 更新:序列化如下
string xmlPayload = null;
XmlSerializer serializer = new XmlSerializer(typeof(Request));
using (StringWriter sw = new StringWriter())
{
using (XmlWriter xw = XmlWriter.Create(sw))
{
serializer.Serialize(xw, payload); // payload is initialized object of Request type
xmlPayload = sw.ToString();
}
}
I solved this by creating InitMethods
, which null unused fields and collections. 我通过创建
InitMethods
来解决此问题,该方法将未使用的字段和集合为空。
So instead of doing 所以不要做
Request request = new Request();
ResultProperties rp = new ResultProperties();
rp.props.Add("foo");
rp.props.Add("bar");
request.properties = rp;
I am doing 我在做
Request InitRequest(RequestFilters filters = null, ResultProperties properties = null)
{
Request request = new Request();
request.filters = filters;
request.properties = properties;
return request;
}
RequestFilters InitRequestFilters(LongFilter ids = null, StringFilter names = null)
{
RequestFilters filters = new RequestFilters();
filters.ids = ids;
filters.names = names;
}
And the same goes for initializing ResultProperties
, LongFilter
and StringFilter
objects. 初始化
ResultProperties
, LongFilter
和StringFilter
对象也是如此。
Then I create request using InitMethods
: 然后,我使用
InitMethods
创建请求:
List<string> properties = new List<string> { "foo", "bar" };
ResultProperties rp = InitResultProperties(properties);
Request request = InitRequest(properties: rp);
And when I serialize the request
, I get just the XML elements which contains actual values and empty elements are omitted from the serialization: 当我序列化
request
,我只得到包含实际值的XML元素,而序列化中忽略了空元素:
<?xml version="1.0" encoding="utf-16"?>
<Request xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<properties>
<props>
<string>foo</string>
<string>bar</string>
</props>
</properties>
</Request>
It is not the optimal solution, because of the overhead of creating the InitMethods
, but I didn't come up with anything better. 由于创建
InitMethods
的开销,它不是最佳解决方案,但是我没有提出更好的选择。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.