Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add prefixes and namespaces to XML serialization

I'm working in a Mexican tax calculation program and the government provided the following XSD file http://www.sat.gob.mx/cfd/3/cfdv32.xsd, with xsd.exe help I have converted it to a C# class which is quite big so I'll just provide a link to it in order to no bloat this post with code: http://pastebin.com/r3VCgFMU.

After filling SOME of the class fields (So the example doesn't get too big) I tried to serialize the XML as follows:

XmlSerializerNamespaces xmlNameSpace = new XmlSerializerNamespaces();
xmlNameSpace.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance");
xmlNameSpace.Add("schemaLocation", "http://www.sat.gob.mx/cfd/3/cfdv32.xsd");
xmlNameSpace.Add("cfdi", "www.sat.gob.mx/cfd/3");
XmlTextWriter xmlTextWriter = new XmlTextWriter("c:\\temp\\pruebas.xml", Encoding.UTF8);
xmlTextWriter.Formatting = Formatting.Indented;
XmlSerializer xs = new XmlSerializer(typeof(Comprobante));

xs.Serialize(xmlTextWriter, comprobante, xmlNameSpace);
xmlTextWriter.Close();

Which gives me this output:

<?xml version="1.0" encoding="utf-8"?>
<Comprobante xmlns:cfdi="www.sat.gob.mx/cfd/3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:schemaLocation="http://www.sat.gob.mx/cfd/3/cfdv32.xsd" version="3.2" fecha="0001-01-01T00:00:00" subTotal="0" total="0" tipoDeComprobante="ingreso" xmlns="http://www.sat.gob.mx/cfd/3">
  <Emisor rfc="DERH9145202V4">
    <DomicilioFiscal calle="Calle1" colonia="Colonia" municipio="municipio" estado="estado" pais="pais" codigoPostal="07000" />
    <RegimenFiscal Regimen="Peque" />
  </Emisor>
</Comprobante>

As we can see in an example provided by the government (ftp://ftp2.sat.gob.mx/asistencia_servicio_ftp/publicaciones/solcedi/ejemplo1%20cfdv3.xml) my generated file lacks some points:

<Comprobante... should be <cfdi:Comprobante 
<Emisor.. should be <cfdi:Emisor 
and so on and so forth with all elements...
xmlns:schemaLocation should be xsi:schemaLocation  
I'm getting and additional xmlns="http://www.sat.gob.mx/cfd/3" at the end of the Comprobante declaration

How can I achieve this changes in my xml? :D

like image 747
Kenny D. Avatar asked May 20 '12 16:05

Kenny D.


People also ask

How do I add namespace prefix to XML element?

To create an attribute that declares a namespace with a prefix, you create an attribute where the namespace of the name of the attribute is Xmlns, and the name of the attribute is the namespace prefix. The value of the attribute is the URI of the namespace.

Is a namespace for XML serialization?

Xml. Serialization namespace contains several Attribute classes that can be applied to members of a class. For example, if a class contains a member that will be serialized as an XML element, you can apply the XmlElementAttribute attribute to the member.

What is the correct way of using XML serialization?

As with the CreatePo method, you must first construct an XmlSerializer, passing the type of class to be deserialized to the constructor. Also, a FileStream is required to read the XML document. To deserialize the objects, call the Deserialize method with the FileStream as an argument.

What is an XML namespace prefix used for?

An XML namespace is a collection of names that can be used as element or attribute names in an XML document. The namespace qualifies element names uniquely on the Web in order to avoid conflicts between elements with the same name.


1 Answers

The problem was solved by a MSDN staff guy, if anyone has the same problem just add:

[XmlAttribute(Namespace = XmlSchema.InstanceNamespace)]
public string schemaLocation = "http://www.sat.gob.mx/cfd/3 cfdv32.xsd";

either to the root class generated by the xsd.exe or to a partial class

(In this example

public partial class Comprobante {

        [XmlAttribute(Namespace = System.Xml.Schema.XmlSchema.InstanceNamespace)]
        public string schemaLocation = "http://www.sat.gob.mx/cfd/3 cfdv32.xsd";
...
}
like image 174
Kenny D. Avatar answered Oct 14 '22 14:10

Kenny D.