2016-12-02 39 views
0

我需要JAXB編組你的幫助。這是關於命名空間的。我在這個神奇的網站上閱讀過不同的博客和很多答案,但是我還沒有意識到如何解決我的問題。JAXB編組和解組和多個命名空間

我需要生成一些棘手的(至少對我來說)命名空間的XML。

<?xml version="1.0" encoding="utf-8"?> 
<cfdi:Comprobante xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd" version="3.2" fecha="2016-11-28T11:04:56" sello="MC7" formaDePago="una sola exhibición" noCertificado="00" certificado="MygA" subTotal="615.52" total="714.00" tipoDeComprobante="ingreso" LugarExpedicion="México DF" NumCtaPago="3138" TipoCambio="1.00" Moneda="MXN" metodoDePago="04" xmlns:cfdi="http://www.sat.gob.mx/cfd/3"> 
<cfdi:Emisor rfc="EMISOR" nombre="EMISOR"> 
<cfdi:DomicilioFiscal calle="SIN NUMERO" noExterior="na" municipio="México DF" estado="México" pais="MEX" codigoPostal="15620" /> 
<cfdi:ExpedidoEn calle="Calle" municipio="México" estado="México" pais="MEX" codigoPostal="63257" /> 
<cfdi:RegimenFiscal Regimen="GENERAL DE LEY PERSONAS MORALES" /> 
</cfdi:Emisor> 
<cfdi:Receptor rfc="EMPRESA" nombre="EMPRESA"> 
<cfdi:Domicilio calle="Ave. Esclavitud No. 5300 " municipio="Mexico" pais="MEX" codigoPostal="52478" /> 
</cfdi:Receptor> 
<cfdi:Conceptos> 
<cfdi:Concepto cantidad="1.0000" unidad="no aplica" noIdentificacion="5213610219" descripcion="CONSUMO" valorUnitario="615.52" importe="615.52" /> 
</cfdi:Conceptos> 
<cfdi:Impuestos totalImpuestosTrasladados="98.48"> 
<cfdi:Traslados> 
<cfdi:Traslado impuesto="IVA" tasa="16.00" importe="98.48" /> 
</cfdi:Traslados> 
</cfdi:Impuestos> 
<cfdi:Complemento> 
<tfd:TimbreFiscalDigital xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sat.gob.mx/TimbreFiscalDigital http://www.sat.gob.mx/sitio_internet/TimbreFiscalDigital/TimbreFiscalDigital.xsd" version="1.0" UUID="070A8-5997-4F11-BCEE" FechaTimbrado="2016-11-28T11:05:05" selloCFD="MC7" noCertificadoSAT="20" selloSAT="In2" xmlns:tfd="http://www.sat.gob.mx/TimbreFiscalDigital" /> 
</cfdi:Complemento> 
<cfdi:Addenda xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://www.voxelgroup.net/xsd https://www.voxelgroup.net/xsd/addenda_v1.xsd" xmlns:voxel="https://www.voxelgroup.net/xsd"> 
    <voxel:AdditionalInfo> 
    </voxel:AdditionalInfo> 
</cfdi:Addenda> 
</cfdi:Comprobante> 

正如你可以看到,這個XML具有

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd"

xmlns:cfdi="http://www.sat.gob.mx/cfd/3" 

我已經完成了不同的測試來解決這個問題,但我還沒有成功。

的Java類,你會看到現在已經有XJC產生的,(沒有getter和setter爲了清楚起見):

 @XmlAccessorType(XmlAccessType.FIELD) 
     @XmlType(name = "", propOrder = { 
      "informacionAduanera", 
      "cuentaPredial", 
      "complementoConcepto", 
      "parte" 
     }) 
     @XmlRootElement(name = "Comprobante", namespace = "http://www.sat.gob.mx/cfd/3") 
     public static class Concepto {    
      @XmlElement(name = "InformacionAduanera") 
      protected List<TInformacionAduanera> informacionAduanera; 
      @XmlElement(name = "CuentaPredial") 
      protected Comprobante.Conceptos.Concepto.CuentaPredial cuentaPredial; 
      @XmlElement(name = "ComplementoConcepto") 
      protected Comprobante.Conceptos.Concepto.ComplementoConcepto complementoConcepto; 
      @XmlElement(name = "Parte") 
      protected List<Comprobante.Conceptos.Concepto.Parte> parte; 
      @XmlAttribute(name = "cantidad", required = true) 
      protected BigDecimal cantidad; 
      @XmlAttribute(name = "unidad", required = true) 
      protected String unidad; 
      @XmlAttribute(name = "noIdentificacion") 
      protected String noIdentificacion; 
      @XmlAttribute(name = "descripcion", required = true) 
      protected String descripcion; 
      @XmlAttribute(name = "valorUnitario", required = true) 
      protected BigDecimal valorUnitario; 
      @XmlAttribute(name = "importe", required = true) 
      protected BigDecimal importe; 
     } 

而且,這是包info.class

@javax.xml.bind.annotation.XmlSchema(namespace = "http://www.w3.org/2001/XMLSchema-instance", 
     elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED) 
package mx.gob.sat.cfd._3; 

我有一個namespaceMapper太:

public class MyNamespaceMapper extends com.sun.xml.bind.marshaller.NamespacePrefixMapper{ 

    private static final String CFDI_URI = "http://www.sat.gob.mx/cfd/3"; 
    private static final String CFDI_PREFIX = "cfdi"; 
    private static final String XSI_URI = "http://www.w3.org/2001/XMLSchema-instance"; 
    private static final String XSI_PREFIX = "";//xsi"; 
    private static final String SCHEMA_URI = "http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd"; 
    private static final String SCHEMA_PREFIX = "";//schemaLocation"; 

    @Override 
    public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requiredPrefix) { 
     switch(namespaceUri){ 
      case CFDI_URI:{ return CFDI_PREFIX; } 
      case XSI_URI:{ return XSI_PREFIX; } 
      case SCHEMA_URI:{ return SCHEMA_PREFIX; } 
      default: { return ""; } 
     } 
    } 
} 

下,這是輸出I得到:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<cfdi:Comprobante xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cfdi="http://www.sat.gob.mx/cfd/3" NumCtaPago="" LugarExpedicion="MEXICO" metodoDePago="02" tipoDeComprobante="ingreso" total="4000.00" Moneda="PESO" TipoCambio="1.0000" motivoDescuento="" descuento="0" subTotal="4000" condicionesDePago="EN UNA SOLA EXHIBICION" certificado="" noCertificado="00009200" formaDePago="CHEQUE" sello="" fecha="2016-12-02T12:40:42.302-06:00" folio="9" serie="A" version="3.2"> 
<xsi:Emisor nombre="PEPITO" rfc="PEPE"> 
<xsi:DomicilioFiscal codigoPostal="51890" pais="México" estado="México" municipio="México" colonia="México" noInterior="" noExterior="5300" calle="Esclavitud"/> 
    <xsi:RegimenFiscal Regimen="Regimen General de Ley Personas Morales"/> 
</xsi:Emisor> 
<xsi:Receptor nombre="EMPRESA" rfc="EMPRESA"> 
    <xsi:Domicilio codigoPostal="51890" pais="México" estado="México" municipio="México" colonia="México" noInterior="" noExterior="5300" calle="Esclavitud"/> 
</xsi:Receptor> 
<xsi:Conceptos> 
    <xsi:Concepto importe="4000" valorUnitario="4000" descripcion="ARRENDAMIENTO DEL MES DE SEPTIEMBRE" unidad="N/A" cantidad="1"/> 
</xsi:Conceptos> 
    <xsi:Impuestos> 
    <xsi:Traslados> 
     <xsi:Traslado importe="400" tasa="10" impuesto="ISR"/> 
    </xsi:Traslados> 
    </xsi:Impuestos> 
</cfdi:Comprobante> 

這是關閉我已經從原始的xml格式。我嘗試了不同的方法,但我沒有更多。

正如你可以看到,在輸出仍然缺少第三個命名空間,

xsi:schemaLocation="http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv32.xsd" 

,每行必須有前綴CFDI沒有XSI

我會很感激任何線索,以完成這件事。

謝謝!

+0

聲明命名空間'「http://www.sat.gob.mx/cfd/3」'在package-info中。 – ulab

回答

0

this example所示,使用@XmlNs註釋來定製NS前綴。

E.g.

@javax.xml.bind.annotation.XmlNs(prefix = "myns", 
       namespaceURI="http://myns/schema" 

這些例子會給你更多的上下文。

即使你能得到的RI類來完成你想要什麼,這是更好地使用這些API比攻入唯一實現類。

0

也許爲時已晚,但我有這樣的事情:

... 
private Map<String, String> prefijos = new HashMap<String, String>(); 
prefijos.put("http://www.w3.org/2001/XMLSchema-instance","xsi"); 
prefijos.put("http://www.sat.gob.mx/cfd/3", "cfdi"); 
prefijos.put("http://www.sat.gob.mx/TimbreFiscalDigital", "tfd"); 
JAXBContext jaxbContext = JAXBContext.newInstance("mx.gob.sat.v33"); 
marshaller = jaxbContext.createMarshaller(); 

marshaller.setProperty("com.sun.xml.bind.namespacePrefixMapper", new 
NamespacePrefixMapperImpl(prefijos)); 
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE); 
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,"http://www.sat.gob.mx/cfd/3 http://www.sat.gob.mx/sitio_internet/cfd/3/cfdv33.xsd"); 

DocumentBuilderFactory docBuilderFac = DocumentBuilderFactory.newInstance(); 
docBuilderFac.setNamespaceAware(true); 
DocumentBuilder db = null; 
db = docBuilderFac.newDocumentBuilder(); 
Document doc = db.newDocument(); 
marshaller.marshal(comprobante,doc); 
... 

我NamespacePrefixMapperImpl是這樣的:

public class NamespacePrefixMapperImpl extends NamespacePrefixMapper{ 
    private final Map<String, String> map; 

    public NamespacePrefixMapperImpl(Map<String, String> map) { 
     this.map = map; 
    } 

    public String getPreferredPrefix(String namespaceUri, String suggestion, 
               boolean requirePrefix) { 
     String value = map.get(namespaceUri); 
     return (value != null) ? value : suggestion; 
    } 

    public String[] getPreDeclaredNamespaceUris() { 
     return new String[0]; 
    } 
} 

也許你可以看看這個project