C# 如何在反序列化类中为根元素设置xmlns前缀

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,但不起作用,问题出在根元素中。这是根元素(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-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);