第一篇中的问题已经弄清楚了,xsd.exe生成的代码是供PC平台使用的,不能保证修改后可以运行在NETCF平台上,我的想法是NETCF中的XmlSerializer与完整版的内部处理逻辑可能不一样,有些方面的处理能力可能有些弱,这里我暂时把Unqualified不能在NETCF中使用的问题归结为NETCF中的BUG,下面调整努力方向为:手工大幅修改xsd.exe自动生成的代码。
<create xmlns="">123</create>中xmlns=""的问题已经弄清楚,正是因为Unqualified的作用使得xml文档中只有根节点具有targetNamespace的命名空间,而其它字节点的命名空间是空的,因此要在每个子节点上面加上xmlns=""的属性,在随后的处理中,我们可以通过在根节点上加前缀来简化xml文档。
冒号的问题暂时还是不清楚,不过对整体的影响不大。
实际上第一篇中介绍的方法生成的xml文档并不符合我的需求,需求中要求根节点具有指定的命名空间,而其它字节点的命名空间为空,而我将Unqualified改为Qualified恰恰破坏了这个规则,因此,后面我将通过其它的方法来处理。
下面为调整后的源代码:
{
[XmlTypeAttribute(Namespace = "")]
[XmlRootAttribute(Namespace = "urn:epcglobal:rp:xsd:1", IsNullable = false)]
public partial class TriggerCommand
{
[XmlElementAttribute(Form = XmlSchemaForm.Qualified)]
public string name;
[XmlElementAttribute("create", typeof(int), Form = XmlSchemaForm.Qualified)]
[XmlElementAttribute("fire", typeof(int), Form = XmlSchemaForm.Qualified)]
[XmlChoiceIdentifierAttribute("ItemElementName")]
public int Item;
[XmlIgnoreAttribute()]
public TriggerCommandItemChoiceType ItemElementName;
}
[XmlTypeAttribute(Namespace = "", IncludeInSchema = false)]
public enum TriggerCommandItemChoiceType
{
[XmlEnumAttribute(Name = "create")]
create,
[XmlEnumAttribute(Name = "fire")]
fire
}
}
[XmlTypeAttribute(Namespace = "")]作用于所有的类型中,正好消除了Qualified带来的命名空间问题,而根节点的命名空间则由[XmlRootAttribute(Namespace = "urn:epcglobal:rp:xsd:1", IsNullable = false)]来限定。
测试代码中序列化的代码调整为:
tc.Item =123;
tc.name = "hello";
XmlSerializer xml = new XmlSerializer(typeof(TriggerCommand));
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("ns", "urn:epcglobal:rp:xsd:1");
FileStream fs = File.Create("a.xml");
xml.Serialize(fs, tc,ns);
fs.Close();
这样最终生成的XML文档中众多的xmlns=""将会被删除,转由根节点的前缀处理,文档大小大幅减少,下面为生成的XML文档:
<ns:TriggerCommand xmlns:ns="urn:epcglobal:rp:xsd:1">
<name>hello</name>
<create>123</create>
</ns:TriggerCommand>
估计这样修改后的源码可能无法通过XSD文档的检验,但是其输出的XML文档是等效的,相同的XML结构应该可以使用不同的XSD来描述。