如何修改Envelope.xsd使序列化后嵌套元素带指定xmlns属性?
问题:修改XSD文件使序列化输出自动添加指定命名空间属性
我创建了名为Envelope.xsd的XSD文件,内容如下:
<w3:schema xmlns:w3="http://www.w3.org/2001/XMLSchema"> <w3:element name="Envelope"> <w3:complexType> <w3:sequence> <w3:element name="Unit"> <w3:complexType> <w3:sequence> <w3:element name="EncryptedData"> <w3:complexType> <w3:sequence> <w3:element name="KeyInfo"> <w3:complexType> <w3:sequence> <w3:element name="KeyName" type="w3:string" /> </w3:sequence> </w3:complexType> </w3:element> </w3:sequence> </w3:complexType> </w3:element> </w3:sequence> </w3:complexType> </w3:element> </w3:sequence> </w3:complexType> </w3:element> </w3:schema>
使用Visual Studio的xsd.exe /c Envelope.xsd命令生成C#代码后,通过以下代码序列化MyEnvelope对象:
var serializer = new XmlSerializer(typeof(Envelope)); var namespaces = new XmlSerializerNamespaces(); namespaces.Add("", ""); var writer = new StringWriter(); serializer.Serialize(writer, MyEnvelope, namespaces); var MyEnvelopeSerialized = writer.ToString();
得到的序列化结果如下:
<Envelope> <Unit> <EncryptedData> <KeyInfo> <KeyName>MyValue</KeyName> </KeyInfo> </EncryptedData> </Unit> </Envelope>
现在需要让序列化输出为以下格式,为<EncryptedData>和<KeyInfo>添加指定的xmlns属性:
<Envelope> <Unit> <EncryptedData xmlns="http://www.w3.org/2001/04/xmlenc#"> <KeyInfo xmlns="http://www.w3.org/2000/09/xmldsig#"> <KeyName>MyValue</KeyName> </KeyInfo> </EncryptedData> </Unit> </Envelope>
解决方案:修改XSD为目标元素指定命名空间
要实现这个需求,需要在XSD中为EncryptedData和KeyInfo分别指定对应的目标命名空间,并通过属性控制命名空间的显示方式。修改后的Envelope.xsd内容如下:
<w3:schema xmlns:w3="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"> <!-- 声明需要使用的外部命名空间 --> <w3:import namespace="http://www.w3.org/2001/04/xmlenc#" /> <w3:import namespace="http://www.w3.org/2000/09/xmldsig#" /> <w3:element name="Envelope"> <w3:complexType> <w3:sequence> <w3:element name="Unit"> <w3:complexType> <w3:sequence> <!-- 为EncryptedData指定加密命名空间 --> <w3:element name="EncryptedData" namespace="http://www.w3.org/2001/04/xmlenc#"> <w3:complexType> <w3:sequence> <!-- 为KeyInfo指定数字签名命名空间 --> <w3:element name="KeyInfo" namespace="http://www.w3.org/2000/09/xmldsig#"> <w3:complexType> <w3:sequence> <w3:element name="KeyName" type="w3:string" /> </w3:sequence> </w3:complexType> </w3:element> </w3:sequence> </w3:complexType> </w3:element> </w3:sequence> </w3:complexType> </w3:element> </w3:sequence> </w3:complexType> </w3:element> </w3:schema>
修改说明:
- 添加
elementFormDefault="qualified":确保局部元素的命名空间会被显式声明,符合目标XML的格式要求。 - 为
EncryptedData元素添加namespace="http://www.w3.org/2001/04/xmlenc#":指定该元素属于加密标准命名空间。 - 为
KeyInfo元素添加namespace="http://www.w3.org/2000/09/xmldsig#":指定该元素属于数字签名标准命名空间。 - 导入外部命名空间:通过
<w3:import>声明依赖的命名空间,保证XSD文件的语法合法性。
后续操作:
- 使用修改后的XSD重新生成C#代码:执行
xsd.exe /c Envelope.xsd命令 - 保持原有的序列化代码不变,执行后即可得到目标格式的XML输出。
内容的提问来源于stack exchange,提问作者Joey
相关产品推荐
相关产品推荐

