C# 如何在反序列化类中为根元素设置xmlns前缀
我曾经创建类帮助器来反序列化特定的XML,但不起作用,问题出在根元素中。这是根元素(RESP_HDR和RESP_BODY已折叠): 问题在于,该类未能像前面所示那样反序列化XML,但成功实现了:C# 如何在反序列化类中为根元素设置xmlns前缀,c#,c#-4.0,xml-serialization,xml-deserialization,C#,C# 4.0,Xml Serialization,Xml Deserialization,我曾经创建类帮助器来反序列化特定的XML,但不起作用,问题出在根元素中。这是根元素(RESP_HDR和RESP_BODY已折叠): 问题在于,该类未能像前面所示那样反序列化XML,但成功实现了: <?xml version="1.0" encoding="UTF-8"?> <RESPUESTA xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-inst
<?xml version="1.0" encoding="UTF-8"?>
<RESPUESTA xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SII="http://www.sii.cl/XMLSchema" xmlns="http://www.sii.cl/XMLSchema">
+ <SII:RESP_HDR>
+ <SII:RESP_BODY>
</RESPUESTA>
+
+
不同之处在于名称空间,即使创建对象并对其进行序列化,结果也是如此。那么,应该在类中更改什么以使其与原始XML一起工作呢
更新:
仔细观察,我发现真正的问题仍然存在于根元素中,但我注意到根标记中缺少xmlns前缀,如何在helper类中设置它 编辑:
这是服务响应中的XML示例:
<?xml version="1.0" encoding="UTF-8"?>
<SII:RESPUESTA xmlns:SII="http://www.sii.cl/XMLSchema">
<SII:RESP_HDR>
<SII:ESTADO>0</SII:ESTADO>
<SII:GLOSA/>
</SII:RESP_HDR>
<SII:RESP_BODY>
<DATOS_CONSULTA>
<RUT>80182144-3</RUT>
<TIPO_CONSULTA>DEUDOR</TIPO_CONSULTA>
<DESDE_DDMMAAAA>01042017</DESDE_DDMMAAAA>
<HASTA_DDMMAAAA>01052017</HASTA_DDMMAAAA>
</DATOS_CONSULTA>
<CESION>
<VENDEDOR>11455447-9</VENDEDOR>
<ESTADO_CESION>Cesion Vigente</ESTADO_CESION>
<DEUDOR>80182144-3</DEUDOR>
<MAIL_DEUDOR/>
<TIPO_DOC>33</TIPO_DOC>
<NOMBRE_DOC>Factura Electronica</NOMBRE_DOC>
<FOLIO_DOC>107</FOLIO_DOC>
<FCH_EMIS_DTE>2017-04-04</FCH_EMIS_DTE>
<MNT_TOTAL>3324860</MNT_TOTAL>
<CEDENTE>11455447-9</CEDENTE>
<RZ_CEDENTE>JHON DOE</RZ_CEDENTE>
<MAIL_CEDENTE>jjdoe@gmail.com</MAIL_CEDENTE>
<CESIONARIO>762327129-7</CESIONARIO>
<RZ_CESIONARIO>capital sa</RZ_CESIONARIO>
<MAIL_CESIONARIO>xcap@capital.com</MAIL_CESIONARIO>
<FCH_CESION>2017-04-05 13:15</FCH_CESION>
<MNT_CESION>3324860</MNT_CESION>
<FCH_VENCIMIENTO>2017-06-04</FCH_VENCIMIENTO>
</CESION>
<CESION>
<VENDEDOR>11455447-9</VENDEDOR>
<ESTADO_CESION>Cesion Vigente</ESTADO_CESION>
<DEUDOR>80182144-3</DEUDOR>
<MAIL_DEUDOR/>
<TIPO_DOC>33</TIPO_DOC>
<NOMBRE_DOC>Factura Electronica</NOMBRE_DOC>
<FOLIO_DOC>34</FOLIO_DOC>
<FCH_EMIS_DTE>2017-03-01</FCH_EMIS_DTE>
<MNT_TOTAL>1725500</MNT_TOTAL>
<CEDENTE>11455447-9</CEDENTE>
<RZ_CEDENTE>JOE DOE</RZ_CEDENTE>
<MAIL_CEDENTE>jd@gmail.com</MAIL_CEDENTE>
<CESIONARIO>762327129-7</CESIONARIO>
<RZ_CESIONARIO>Capital S.A.</RZ_CESIONARIO>
<MAIL_CESIONARIO>jcap@capital.com</MAIL_CESIONARIO>
<FCH_CESION>2017-04-05 17:27</FCH_CESION>
<MNT_CESION>1725500</MNT_CESION>
<FCH_VENCIMIENTO>2017-03-01</FCH_VENCIMIENTO>
</CESION>
</SII:RESP_BODY>
</SII:RESPUESTA>
0
80182144-3
德乌多
01042017
01052017
11455447-9
维根特宫
80182144-3
33
电子事实
107
2017-04-04
3324860
11455447-9
约翰·多伊
jjdoe@gmail.com
762327129-7
首都南非
xcap@capital.com
2017-04-05 13:15
3324860
2017-06-04
11455447-9
维根特宫
80182144-3
33
电子事实
34
2017-03-01
1725500
11455447-9
乔·多伊
jd@gmail.com
762327129-7
首都S.A。
jcap@capital.com
2017-04-05 17:27
1725500
2017-03-01
到目前为止,我能让它工作的唯一方法是使用一个非常丑陋的解决方案,这不应该被认为是问题的答案
//Query service to obtain XML response
string xmlResponse = siiClient.QueryDocuments(documentsRequest);
//Replace RESPUESTA tags in the XML response, remove the prefix SII
var replacedXML = xmlResponse .Replace("SII:RESPUESTA", "RESPUESTA" );
//Load XML string into XmlDocument
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(replacedXML);
//Add missing namespaces
xDoc.DocumentElement.SetAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
xDoc.DocumentElement.SetAttribute("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
xDoc.DocumentElement.SetAttribute("xmlns", "http://www.sii.cl/XMLSchema");
//Now deserialization will work
var documentResponse = xDoc.ParseXML<RESPUESTA>();
//查询服务以获取XML响应
字符串xmlResponse=siiClient.QueryDocuments(documentsRequest);
//替换XML响应中的RESPUESTA标记,删除前缀SII
var replacedXML=xmlResponse.Replace(“SII:RESPUESTA”、“RESPUESTA”);
//将XML字符串加载到XmlDocument中
XmlDocument xDoc=新的XmlDocument();
LoadXml(replacedXML);
//添加缺少的名称空间
xDoc.DocumentElement.SetAttribute(“xmlns:xsi,”http://www.w3.org/2001/XMLSchema-instance");
xDoc.DocumentElement.SetAttribute(“xmlns:xsd,”http://www.w3.org/2001/XMLSchema");
xDoc.DocumentElement.SetAttribute(“xmlns”http://www.sii.cl/XMLSchema");
//现在反序列化将起作用
var documentResponse=xDoc.ParseXML();
理想的解决方案是采用XML响应并直接对其进行反序列化,而无需任何预处理,如:
//Query service to obtain XML response
string xmlResponse = siiClient.QueryDocuments(documentsRequest);
//ParseXML is an extension method, it can handle an string or an XmlDocument
var documentResponse = xmlResponse.ParseXML<RESPUESTA>();
//查询服务以获取XML响应
字符串xmlResponse=siiClient.QueryDocuments(documentsRequest);
//ParseXML是一种扩展方法,它可以处理字符串或XmlDocument
var documentResponse=xmlResponse.ParseXML();
注意:ParseXML基于我获取了您的xml:
<?xml version="1.0" encoding="UTF-8"?>
<SII:RESPUESTA xmlns:SII="http://www.sii.cl/XMLSchema">
<SII:RESP_HDR/>
<SII:RESP_BODY/>
</SII:RESPUESTA>
刚刚添加了两个空的类存根
尝试System.Xml.Serialization.XmlSerializer
:
RESPUESTA respuesta;
var xs = new XmlSerializer(typeof(RESPUESTA));
using (var fs = new FileStream("test.xml", FileMode.Open))
respuesta = (RESPUESTA)xs.Deserialize(fs);
它起作用了!我不明白它如何以及为什么不适用于您。两种XML都是相同的。它们具有相同的元素名称和名称空间。名称空间前缀是不相关的。仍然不起作用,到目前为止,我能使它起作用的唯一方法是修改获得的XML,将前缀SII添加到标记
RESPUESTA
,然后添加其余的名称空间,然后反序列化此XML。我的意思是从标记RESPUESTA
Petrov中“删除”前缀SII,我从未提到尝试反序列化时出错,只是结果是一个空对象,就像您得到的一样。我已经从服务响应中添加了一个XML示例,也许您可以再试一次。请记住,我在中生成了类,我刚刚为问题添加了更多详细信息,并对您的答案进行了注释,谢谢您的关注。@AlexanderPetrov您是对的,无论哪种方式,它都是有效的XML,但是您经常会遇到自定义编写的XML验证,它会坚持XML元素以某种方式进行结构,这就是为什么我要这样做的原因,一些白痴坚持要我在根元素中添加前缀:|这个答案很糟糕,顺便说一句,不要这样做。@tonyenkiducx-我同意。客户通常坚持使用特定的格式。我试图向他们解释,挥舞着xml标准。。。没有帮助。我发现了最可能的问题是什么,与不发布所有代码有关;)您的序列化程序可能缺少命名空间的提示,因此未添加前缀,或者您可能正在将空根属性添加到序列化程序()中
<?xml version="1.0" encoding="UTF-8"?>
<SII:RESPUESTA xmlns:SII="http://www.sii.cl/XMLSchema">
<SII:RESP_HDR/>
<SII:RESP_BODY/>
</SII:RESPUESTA>
[XmlRoot(ElementName = "RESPUESTA", Namespace = "http://www.sii.cl/XMLSchema")]
public class RESPUESTA
{
[XmlElement(ElementName = "RESP_HDR", Namespace = "http://www.sii.cl/XMLSchema")]
public RESP_HDR RESP_HDR { get; set; }
[XmlElement(ElementName = "RESP_BODY", Namespace = "http://www.sii.cl/XMLSchema")]
public RESP_BODY RESP_BODY { get; set; }
[XmlAttribute(AttributeName = "SII", Namespace = "http://www.w3.org/2000/xmlns/")]
public string SII { get; set; }
}
public class RESP_HDR { }
public class RESP_BODY { }
RESPUESTA respuesta;
var xs = new XmlSerializer(typeof(RESPUESTA));
using (var fs = new FileStream("test.xml", FileMode.Open))
respuesta = (RESPUESTA)xs.Deserialize(fs);