的子元素发现了非法的文本数据



我正在尝试将xml转换为Spring MVC 4中的对象。但是我得到了这个错误(只是其中的一部分):

Caused by: org.xml.sax.SAXException: Illegal Text data found as child of: comprobante
  value: "<?xml version="1.0" encoding="UTF-8"?> <comprobanteRetencion id="comprobante" version="1.0.0"> <infoTributaria> <ambiente>2</ambiente> <tipoEmision>1</tipoEmision> <razonSocial> ... (resto del XML)
    at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:874)
    at org.exolab.castor.xml.UnmarshalHandler.endElement(UnmarshalHandler.java:1159)
    at org.apache.xerces.parsers.AbstractSAXParser.endElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanEndElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.springframework.oxm.castor.CastorMarshaller.unmarshalSaxReader(CastorMarshaller.java:632)
    ... 74 more

这是我试图转换的一段xml(它太大了):

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<autorizacion>
    <estado>AUTORIZADO</estado>
    <numeroAutorizacion>888888888888888888</numeroAutorizacion>
    <fechaAutorizacion>17/06/2015 09:13:17</fechaAutorizacion>
    <comprobante><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<comprobanteRetencion id="comprobante" version="1.0.0">
  <infoTributaria>
    <ambiente>2</ambiente>
    <tipoEmision>1</tipoEmision>
    <razonSocial>UNA RAZON CUALQUIRA</razonSocial>
    <ruc>1760005540001</ruc>
    <claveAcceso>6876876876868768768762500110050000670914</claveAcceso>
    <codDoc>07</codDoc>
    <estab>001</estab>
    <ptoEmi>025</ptoEmi>
    <secuencial>000000005</secuencial>
    <dirMatriz>AV. AMERICA</dirMatriz>
  </infoTributaria>
  <infoCompRetencion>
    <fechaEmision>16/06/2015</fechaEmision>
    <dirEstablecimiento>AV. AMERICA</dirEstablecimiento>
    <contribuyenteEspecial>666</contribuyenteEspecial>
    <tipoIdentificacionSujetoRetenido>04</tipoIdentificacionSujetoRetenido>
    <razonSocialSujetoRetenido>S.A.</razonSocialSujetoRetenido>
    <identificacionSujetoRetenido>99999999999</identificacionSujetoRetenido>
    <periodoFiscal>06/2015</periodoFiscal>
  </infoCompRetencion> ...

这是mapping.xml文件:

<mapping>
    <class name="ec.eac.sitac.esigef.Comprobante">
        <map-to xml="comprobante" />
        <field name="version" type="java.lang.String">
            <bind-xml name="version" node="attribute" />
        </field>
        <field name="encoding" type="java.lang.String">
            <bind-xml name="encoding" node="attribute" />
        </field>
        <field name="comprobanteRetencion" type="ec.eac.sitac.esigef.ComprobanteRetencion">
            <bind-xml name="comprobanteRetencion" node="element" />
        </field>
    </class>
    <class name="ec.eac.sitac.esigef.ESIGEF_XMLObject">
        <map-to xml="autorizacion" />
        <field name="estado" type="java.lang.String">
            <bind-xml name="estado" node="element" />
        </field>
        <field name="numeroAutorizacion" type="java.lang.String">
            <bind-xml name="numeroAutorizacion" node="element" />
        </field>
        <field name="fechaAutorizacion" type="java.lang.String">
            <bind-xml name="fechaAutorizacion" node="element" />
        </field>
        <field name="comprobante" type="ec.eac.sitac.esigef.Comprobante">
            <bind-xml name="comprobante" node="element" />
        </field>
    </class>
    <class name="ec.eac.sitac.esigef.InfoCompRetencion">
        <map-to xml="infoCompRetencion" />
        <field name="fechaEmision" type="java.lang.String">
            <bind-xml name="fechaEmision" node="element" />
        </field>
        <field name="dirEstablecimiento" type="java.lang.String">
            <bind-xml name="dirEstablecimiento" node="element" />
        </field>
        <field name="contribuyenteEspecial" type="java.lang.String">
            <bind-xml name="contribuyenteEspecial" node="element" />
        </field>
        <field name="tipoIdentificacionSujetoRetenido" type="java.lang.String">
            <bind-xml name="tipoIdentificacionSujetoRetenido" node="element" />
        </field>
        <field name="razonSocialSujetoRetenido" type="java.lang.String">
            <bind-xml name="razonSocialSujetoRetenido" node="element" />
        </field>
        <field name="identificacionSujetoRetenido" type="java.lang.String">
            <bind-xml name="identificacionSujetoRetenido" node="element" />
        </field>
        <field name="periodoFiscal" type="java.lang.String">
            <bind-xml name="periodoFiscal" node="element" />
        </field>
    </class>
    <class name="ec.eac.sitac.esigef.InfoTributaria">
        <map-to xml="infoTributaria" />
        <field name="ambiente" type="java.lang.String">
            <bind-xml name="ambiente" node="element" />
        </field>
        <field name="tipoEmision" type="java.lang.String">
            <bind-xml name="tipoEmision" node="element" />
        </field>
        <field name="razonSocial" type="java.lang.String">
            <bind-xml name="razonSocial" node="element" />
        </field>
        <field name="ruc" type="java.lang.String">
            <bind-xml name="ruc" node="element" />
        </field>
        <field name="claveAcceso" type="java.lang.String">
            <bind-xml name="claveAcceso" node="element" />
        </field>
        <field name="codDoc" type="java.lang.String">
            <bind-xml name="codDoc" node="element" />
        </field>
        <field name="estab" type="java.lang.String">
            <bind-xml name="estab" node="element" />
        </field>
        <field name="ptoEmi" type="java.lang.String">
            <bind-xml name="ptoEmi" node="element" />
        </field>
        <field name="secuencial" type="java.lang.String">
            <bind-xml name="secuencial" node="element" />
        </field>
        <field name="dirMatriz" type="java.lang.String">
            <bind-xml name="dirMatriz" node="element" />
        </field>
    </class>
    <class name="ec.eac.sitac.esigef.ComprobanteRetencion">
        <map-to xml="comprobanteRetencion" />
        <field name="id" type="java.lang.String">
            <bind-xml name="id" node="attribute" />
        </field>
        <field name="version" type="java.lang.String">
            <bind-xml name="version" node="attribute" />
        </field>
        <field name="infoTributaria" type="ec.eac.sitac.esigef.InfoTributaria">
            <bind-xml name="infoTributaria" node="element" />
        </field>
        <field name="infoCompRetencion" type="ec.eac.sitac.esigef.InfoCompRetencion">
            <bind-xml name="infoCompRetencion" node="element" />
        </field>
        <field name="impuestos" type="ec.eac.sitac.esigef.Impuesto" collection="arraylist">
            <bind-xml name="impuestos" />
        </field>
        <field name="infoAdicional" type="ec.eac.sitac.esigef.InfoAdicional">
            <bind-xml name="infoAdicional" node="element" />
        </field>
    </class>
</mapping>

有人知道得到这个错误的原因吗?之前有人在stackoverflow上贴了这个问题,但是答案被删除了。

根据映射,comprobante元素应该有名为comprobanteRetencion的子元素,但是在您的输入XML文件中,comprobante元素包含文本。这就是Castor抱怨的原因

最后,我将xml转换为字符串。

private static String convertDocumentToString(Document doc) {
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer;
    try {
        transformer = tf.newTransformer();
        // below code to remove XML declaration
        // transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
        StringWriter writer = new StringWriter();
        transformer.transform(new DOMSource(doc), new StreamResult(writer));
        String output = writer.getBuffer().toString();
        return output;
    } catch (TransformerException e) {
        e.printStackTrace();
    }
    return null;
}

之后,我通过替换它来删除CDATA标签:

    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
    Document doc = docBuilder.parse(filePath);
    String text = convertDocumentToString(doc);
    String pattern = "<![CDATA[<?xml version=" + """ + "1.0" + """ + " encoding=" + """ + "UTF-8" + ""?>";
    text = text.replace(pattern, "");  
    text = text.replace("]]>", ""); 
    doc = convertStringToDocument(text);

最后,我使用以下方法将字符串转换回XML:

private static Document convertStringToDocument(String xmlStr) {
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();  
    DocumentBuilder builder;  
    try 
    {  
        builder = factory.newDocumentBuilder();  
        Document doc = builder.parse( new InputSource( new StringReader( xmlStr ) ) ); 
        return doc;
    } catch (Exception e) {  
        e.printStackTrace();  
    } 
    return null;
}

最新更新