使用命名空间将 类 序列化为 XML
Serialize classes to XML with namespaces
我实际上正在努力将我的 classes 序列化为所需的 XML。我在以正确的方式放置名称空间时遇到问题。
这是需要的XML:
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://abc.def.schema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<q0:LoginScopeHeader>
<organizationName>WebService Test Account</organizationName>
</q0:LoginScopeHeader>
<q0:SessionHeader>
<sessionId>00f63ba748474ebba5a5ce0f8fdf7ac4</sessionId>
</q0:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<q0:GroupSet>
<staticGroup>
<number>10000</number>
<name>Gruppe A</name>
<conference>false</conference>
<activated>true</activated>
<personsCounter>0</personsCounter>
<messageName xsi:nil="true"/>
<personNumber xsi:nil="true"/>
</staticGroup>
<staticGroup>
<number>10000</number>
<name>Gruppe A</name>
<conference>false</conference>
<activated>true</activated>
<personsCounter>0</personsCounter>
<messageName xsi:nil="true"/>
<personNumber xsi:nil="true"/>
</staticGroup>
</q0:GroupSet>
</soapenv:Body>
实际上我的 class 表示是这样的:
[XmlRoot(ElementName = "Envelope")]
public class Envelope
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body")]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "soapenv")]
public string Soapenv { get; set; }
[XmlAttribute(AttributeName = "q0")]
public string Q0 { get; set; }
[XmlAttribute(AttributeName = "xsd")]
public string Xsd { get; set; }
[XmlAttribute(AttributeName = "xsi")]
public string Xsi { get; set; }
}
[XmlRoot(ElementName = "LoginScopeHeader")]
public class LoginScopeHeader
{
[XmlElement(ElementName = "organizationName")]
public string OrganizationName { get; set; }
}
[XmlRoot(ElementName = "SessionHeader")]
public class SessionHeader
{
[XmlElement(ElementName = "sessionId")]
public string SessionId { get; set; }
}
[XmlRoot(ElementName = "Header")]
public class Header
{
[XmlElement(ElementName = "LoginScopeHeader")]
public LoginScopeHeader LoginScopeHeader { get; set; }
[XmlElement(ElementName = "SessionHeader")]
public SessionHeader SessionHeader { get; set; }
}
[XmlRoot(ElementName = "Body")]
public class Body
{
[XmlElement(ElementName = "GroupSet")]
public GroupSet GroupSet { get; set; }
}
[XmlRoot(ElementName = "GroupSet")]
public class GroupSet
{
[XmlElement(ElementName = "staticGroup")]
public List<StaticGroup> StaticGroup { get; set; }
}
[XmlRoot(ElementName = "staticGroup")]
public class StaticGroup
{
[XmlElement(ElementName = "number")]
public string Number { get; set; }
[XmlElement(ElementName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "conference")]
public string Conference { get; set; }
[XmlElement(ElementName = "activated")]
public string Activated { get; set; }
[XmlElement(ElementName = "personsCounter")]
public string PersonsCounter { get; set; }
[XmlElement(ElementName = "messageName")]
public MessageName MessageName { get; set; }
[XmlElement(ElementName = "personNumber")]
public PersonNumber PersonNumber { get; set; }
}
[XmlRoot(ElementName = "messageName")]
public class MessageName
{
[XmlAttribute(AttributeName = "nil")]
public string Nil { get; set; }
}
[XmlRoot(ElementName = "personNumber")]
public class PersonNumber
{
[XmlAttribute(AttributeName = "nil")]
public string Nil { get; set; }
}
这里是序列化的扩展方法:
public static string XmlSerialize<T>(this T item, bool removeNamespaces = true)
{
object locker = new object();
XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
xmlns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
xmlns.Add("xsd", "http://www.w3.org/2001/XMLSchema");
xmlns.Add("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
lock (locker)
{
StringBuilder stringBuilder = new StringBuilder();
using (StringWriter stringWriter = new StringWriter(stringBuilder))
{
using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings))
{
if (removeNamespaces)
{
xmlSerializer.Serialize(xmlWriter, item, xmlns);
}
else { xmlSerializer.Serialize(xmlWriter, item); }
return stringBuilder.ToString();
}
}
}
}
我实际上不知道如何像上面那样序列化命名空间 XML。
我想念什么?非常感谢任何帮助
UPDATE_1:
我已经按照 jdweng 的建议添加了命名空间,如下所示:
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body")]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "soapenv")]
public string Soapenv { get; set; }
[XmlAttribute(AttributeName = "q0")]
public string Q0 { get; set; }
[XmlAttribute(AttributeName = "xsd")]
public string Xsd { get; set; }
[XmlAttribute(AttributeName = "xsi")]
public string Xsi { get; set; }
}
[XmlRoot(ElementName = "Header", Namespace = http://schemas.xmlsoap.org/soap/envelope/")]
public class Header
{
[XmlElement(ElementName = "LoginScopeHeader")]
public LoginScopeHeader LoginScopeHeader { get; set; }
[XmlElement(ElementName = "SessionHeader")]
public SessionHeader SessionHeader { get; set; }
}
[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
[XmlElement(ElementName = "PersonSet")]
public PersonSet PersonSet { get; set; }
}
但现在我得到以下 XML:
<soapenv:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<soapenv:LoginScopeHeader>
<soapenv:organizationName>Blablabla</soapenv:organizationName>
</soapenv:LoginScopeHeader>
<soapenv:SessionHeader>
<soapenv:sessionId>654654654654654654654</soapenv:sessionId>
</soapenv:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<soapenv:PersonSet>
<soapenv:elements>
<soapenv:active>true</soapenv:active>
<soapenv:number>321321321</soapenv:number>
<soapenv:name1>John</soapenv:name1>
<soapenv:name2>Doe</soapenv:name2>
<soapenv:language>DE</soapenv:language>
<soapenv:extra />
<soapenv:remarks>remarks</soapenv:remarks>
<soapenv:pin>65454</soapenv:pin>
<soapenv:onDutyManagement>false</soapenv:onDutyManagement>
<soapenv:onDutyManagementAutomaticLogoutDuration>0</soapenv:onDutyManagementAutomaticLogoutDuration>
<soapenv:onDutyManagementNotification>false</soapenv:onDutyManagementNotification>
<soapenv:contactDataManager>false</soapenv:contactDataManager>
<soapenv:contactDataManagedBy nil="1" />
<soapenv:caseManagerAccessMode>NO_ACCESS</soapenv:caseManagerAccessMode>
<soapenv:plannedPeriodsOfAbsence nil="1" />
<soapenv:groups>
<soapenv:elements>
<soapenv:active>true</soapenv:active>
<soapenv:conference_moderator>false</soapenv:conference_moderator>
<soapenv:time_offset>0</soapenv:time_offset>
<soapenv:groupNumber>123456</soapenv:groupNumber>
</soapenv:elements>
</soapenv:groups>
<soapenv:devices>
<soapenv:elements>
<soapenv:callingNumberOrEmail>s_c@gmx.ch</soapenv:callingNumberOrEmail>
<soapenv:prio_working_hours>1</soapenv:prio_working_hours>
<soapenv:prio_non_working_hours>0</soapenv:prio_non_working_hours>
<soapenv:dtmfExtensionNumber />
<soapenv:deviceName>EMail Privat</soapenv:deviceName>
</soapenv:elements>
</soapenv:devices>
</soapenv:elements>
</soapenv:PersonSet>
</soapenv:Body>
</soapenv:Envelope>
您需要为您的序列化属性分配适当的命名空间。 Envelope、Body 和 Header 元素具有命名空间 http://schemas.xmlsoap.org/soap/envelope/
。所以你的 Envelope
class 应该是这样的:
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body")]
public Body Body { get; set; }
}
您已将名称空间前缀 (q0、xsi、xsd) 添加为 Envelope
class 的属性,这不是必需的,因此您可以删除它们。
涉及的另一个名称空间是 http://abc.def.schema
,它具有 q0
前缀。您应该在顶层需要的地方分配它,例如,在 Body
class 中,它应该分配给 GroupSet
属性:
[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
[XmlElement(ElementName = "GroupSet", Namespace = "http://abc.def.schema")]
public GroupSet GroupSet { get; set; }
}
当你开始序列化时,此刻你并没有告诉序列化器关于 q0
命名空间前缀的信息。所以你需要在你的 XmlSerialize<T>
扩展方法中添加这个:
xmlns.Add("q0", "http://abc.def.schema");
您的 StaticGroup
元素没有在您的示例 XML 中定义的名称空间。所以你的 GroupSet
需要在这里定义一个空的命名空间:
[XmlRoot(ElementName = "GroupSet", Namespace = "http://abc.def.schema")]
public class GroupSet
{
[XmlElement(ElementName = "staticGroup", Namespace = "")]
public List<StaticGroup> StaticGroup { get; set; }
}
我实际上正在努力将我的 classes 序列化为所需的 XML。我在以正确的方式放置名称空间时遇到问题。
这是需要的XML:
<?xml version="1.0" encoding="UTF-8"?> <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:q0="http://abc.def.schema" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Header>
<q0:LoginScopeHeader>
<organizationName>WebService Test Account</organizationName>
</q0:LoginScopeHeader>
<q0:SessionHeader>
<sessionId>00f63ba748474ebba5a5ce0f8fdf7ac4</sessionId>
</q0:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<q0:GroupSet>
<staticGroup>
<number>10000</number>
<name>Gruppe A</name>
<conference>false</conference>
<activated>true</activated>
<personsCounter>0</personsCounter>
<messageName xsi:nil="true"/>
<personNumber xsi:nil="true"/>
</staticGroup>
<staticGroup>
<number>10000</number>
<name>Gruppe A</name>
<conference>false</conference>
<activated>true</activated>
<personsCounter>0</personsCounter>
<messageName xsi:nil="true"/>
<personNumber xsi:nil="true"/>
</staticGroup>
</q0:GroupSet>
</soapenv:Body>
实际上我的 class 表示是这样的:
[XmlRoot(ElementName = "Envelope")]
public class Envelope
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body")]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "soapenv")]
public string Soapenv { get; set; }
[XmlAttribute(AttributeName = "q0")]
public string Q0 { get; set; }
[XmlAttribute(AttributeName = "xsd")]
public string Xsd { get; set; }
[XmlAttribute(AttributeName = "xsi")]
public string Xsi { get; set; }
}
[XmlRoot(ElementName = "LoginScopeHeader")]
public class LoginScopeHeader
{
[XmlElement(ElementName = "organizationName")]
public string OrganizationName { get; set; }
}
[XmlRoot(ElementName = "SessionHeader")]
public class SessionHeader
{
[XmlElement(ElementName = "sessionId")]
public string SessionId { get; set; }
}
[XmlRoot(ElementName = "Header")]
public class Header
{
[XmlElement(ElementName = "LoginScopeHeader")]
public LoginScopeHeader LoginScopeHeader { get; set; }
[XmlElement(ElementName = "SessionHeader")]
public SessionHeader SessionHeader { get; set; }
}
[XmlRoot(ElementName = "Body")]
public class Body
{
[XmlElement(ElementName = "GroupSet")]
public GroupSet GroupSet { get; set; }
}
[XmlRoot(ElementName = "GroupSet")]
public class GroupSet
{
[XmlElement(ElementName = "staticGroup")]
public List<StaticGroup> StaticGroup { get; set; }
}
[XmlRoot(ElementName = "staticGroup")]
public class StaticGroup
{
[XmlElement(ElementName = "number")]
public string Number { get; set; }
[XmlElement(ElementName = "name")]
public string Name { get; set; }
[XmlElement(ElementName = "conference")]
public string Conference { get; set; }
[XmlElement(ElementName = "activated")]
public string Activated { get; set; }
[XmlElement(ElementName = "personsCounter")]
public string PersonsCounter { get; set; }
[XmlElement(ElementName = "messageName")]
public MessageName MessageName { get; set; }
[XmlElement(ElementName = "personNumber")]
public PersonNumber PersonNumber { get; set; }
}
[XmlRoot(ElementName = "messageName")]
public class MessageName
{
[XmlAttribute(AttributeName = "nil")]
public string Nil { get; set; }
}
[XmlRoot(ElementName = "personNumber")]
public class PersonNumber
{
[XmlAttribute(AttributeName = "nil")]
public string Nil { get; set; }
}
这里是序列化的扩展方法:
public static string XmlSerialize<T>(this T item, bool removeNamespaces = true)
{
object locker = new object();
XmlSerializerNamespaces xmlns = new XmlSerializerNamespaces();
xmlns.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
xmlns.Add("xsd", "http://www.w3.org/2001/XMLSchema");
xmlns.Add("soapenv", "http://schemas.xmlsoap.org/soap/envelope/");
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.OmitXmlDeclaration = true;
lock (locker)
{
StringBuilder stringBuilder = new StringBuilder();
using (StringWriter stringWriter = new StringWriter(stringBuilder))
{
using (XmlWriter xmlWriter = XmlWriter.Create(stringWriter, settings))
{
if (removeNamespaces)
{
xmlSerializer.Serialize(xmlWriter, item, xmlns);
}
else { xmlSerializer.Serialize(xmlWriter, item); }
return stringBuilder.ToString();
}
}
}
}
我实际上不知道如何像上面那样序列化命名空间 XML。
我想念什么?非常感谢任何帮助
UPDATE_1:
我已经按照 jdweng 的建议添加了命名空间,如下所示:
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body")]
public Body Body { get; set; }
[XmlAttribute(AttributeName = "soapenv")]
public string Soapenv { get; set; }
[XmlAttribute(AttributeName = "q0")]
public string Q0 { get; set; }
[XmlAttribute(AttributeName = "xsd")]
public string Xsd { get; set; }
[XmlAttribute(AttributeName = "xsi")]
public string Xsi { get; set; }
}
[XmlRoot(ElementName = "Header", Namespace = http://schemas.xmlsoap.org/soap/envelope/")]
public class Header
{
[XmlElement(ElementName = "LoginScopeHeader")]
public LoginScopeHeader LoginScopeHeader { get; set; }
[XmlElement(ElementName = "SessionHeader")]
public SessionHeader SessionHeader { get; set; }
}
[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
[XmlElement(ElementName = "PersonSet")]
public PersonSet PersonSet { get; set; }
}
但现在我得到以下 XML:
<soapenv:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header>
<soapenv:LoginScopeHeader>
<soapenv:organizationName>Blablabla</soapenv:organizationName>
</soapenv:LoginScopeHeader>
<soapenv:SessionHeader>
<soapenv:sessionId>654654654654654654654</soapenv:sessionId>
</soapenv:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<soapenv:PersonSet>
<soapenv:elements>
<soapenv:active>true</soapenv:active>
<soapenv:number>321321321</soapenv:number>
<soapenv:name1>John</soapenv:name1>
<soapenv:name2>Doe</soapenv:name2>
<soapenv:language>DE</soapenv:language>
<soapenv:extra />
<soapenv:remarks>remarks</soapenv:remarks>
<soapenv:pin>65454</soapenv:pin>
<soapenv:onDutyManagement>false</soapenv:onDutyManagement>
<soapenv:onDutyManagementAutomaticLogoutDuration>0</soapenv:onDutyManagementAutomaticLogoutDuration>
<soapenv:onDutyManagementNotification>false</soapenv:onDutyManagementNotification>
<soapenv:contactDataManager>false</soapenv:contactDataManager>
<soapenv:contactDataManagedBy nil="1" />
<soapenv:caseManagerAccessMode>NO_ACCESS</soapenv:caseManagerAccessMode>
<soapenv:plannedPeriodsOfAbsence nil="1" />
<soapenv:groups>
<soapenv:elements>
<soapenv:active>true</soapenv:active>
<soapenv:conference_moderator>false</soapenv:conference_moderator>
<soapenv:time_offset>0</soapenv:time_offset>
<soapenv:groupNumber>123456</soapenv:groupNumber>
</soapenv:elements>
</soapenv:groups>
<soapenv:devices>
<soapenv:elements>
<soapenv:callingNumberOrEmail>s_c@gmx.ch</soapenv:callingNumberOrEmail>
<soapenv:prio_working_hours>1</soapenv:prio_working_hours>
<soapenv:prio_non_working_hours>0</soapenv:prio_non_working_hours>
<soapenv:dtmfExtensionNumber />
<soapenv:deviceName>EMail Privat</soapenv:deviceName>
</soapenv:elements>
</soapenv:devices>
</soapenv:elements>
</soapenv:PersonSet>
</soapenv:Body>
</soapenv:Envelope>
您需要为您的序列化属性分配适当的命名空间。 Envelope、Body 和 Header 元素具有命名空间 http://schemas.xmlsoap.org/soap/envelope/
。所以你的 Envelope
class 应该是这样的:
[XmlRoot(ElementName = "Envelope", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Envelope
{
[XmlElement(ElementName = "Header")]
public Header Header { get; set; }
[XmlElement(ElementName = "Body")]
public Body Body { get; set; }
}
您已将名称空间前缀 (q0、xsi、xsd) 添加为 Envelope
class 的属性,这不是必需的,因此您可以删除它们。
涉及的另一个名称空间是 http://abc.def.schema
,它具有 q0
前缀。您应该在顶层需要的地方分配它,例如,在 Body
class 中,它应该分配给 GroupSet
属性:
[XmlRoot(ElementName = "Body", Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public class Body
{
[XmlElement(ElementName = "GroupSet", Namespace = "http://abc.def.schema")]
public GroupSet GroupSet { get; set; }
}
当你开始序列化时,此刻你并没有告诉序列化器关于 q0
命名空间前缀的信息。所以你需要在你的 XmlSerialize<T>
扩展方法中添加这个:
xmlns.Add("q0", "http://abc.def.schema");
您的 StaticGroup
元素没有在您的示例 XML 中定义的名称空间。所以你的 GroupSet
需要在这里定义一个空的命名空间:
[XmlRoot(ElementName = "GroupSet", Namespace = "http://abc.def.schema")]
public class GroupSet
{
[XmlElement(ElementName = "staticGroup", Namespace = "")]
public List<StaticGroup> StaticGroup { get; set; }
}