2012-03-20 18 views
5

Necesito validar el xml grande con uso de memoria limitado. Con cada código que he encontrado hasta ahora, me sale el error de memoria.¿Cómo validar big xml contra el esquema xsd?

Métodos Traté:

//method 1 
     SAXParserFactory factory = SAXParserFactory.newInstance(); 
     factory.setValidating(false); 
     factory.setNamespaceAware(true); 

     SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); 
     factory.setSchema(schemaFactory.newSchema(new Source[] {new StreamSource(Thread.currentThread().getContextClassLoader().getResource("xmlresource/XSD_final2.xsd").getFile())})); 
     SAXParser parser = factory.newSAXParser(); 
     XMLReader reader = parser.getXMLReader(); 
     reader.setErrorHandler(new SimpleErrorHandler()); 
     reader.parse(new InputSource(inputXml)); 
//method2 

XMLValidationSchemaFactory sf = XMLValidationSchemaFactory.newInstance(XMLValidationSchema.SCHEMA_ID_W3C_SCHEMA); 
      XMLValidationSchema vs = sf.createSchema(Thread.currentThread().getContextClassLoader().getResource("xmlresource/XSD_final2.xsd")); 
      XMLStreamReader2 sr = (XMLStreamReader2) XMLInputFactory2.newInstance().createXMLStreamReader(new FileInputStream(inputXml)); 
      sr.validateAgainst(vs); 
      try { 
       while (sr.hasNext()) { 
       sr.next(); 
       } 
       System.out.println("Validated ok!"); 
      } catch (XMLValidationException ve) { 
       System.err.println("Validation problem: "+ve); 
       isValid = false; 
      } 
      sr.close(); 

// Método 3

 SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); 
      String fileName = Thread.currentThread().getContextClassLoader().getResource("xmlresource/XSD_final2.xsd").getFile(); 

      Schema schema = factory.newSchema(new File(fileName)); 
      Validator validator = schema.newValidator(); 

      // create a source from a file 
      StreamSource source = new StreamSource(new File(inputXml)); 

      // check input 

      validator.validate(source); 

me sale cada vez que OutOfMemory

EDITAR

con XOM

SAXParserFactory factory = SAXParserFactory.newInstance(); 
      factory.setValidating(false); 
      factory.setNamespaceAware(true); 

      SchemaFactory schemaFactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); 
      factory.setSchema(schemaFactory.newSchema(new Source[] {new StreamSource(Thread.currentThread().getContextClassLoader().getResource("xmlresource/XSD_final2.xsd").getFile())})); 
      SAXParser parser = factory.newSAXParser(); 
      XMLReader reader = parser.getXMLReader(); 
      reader.setErrorHandler(new SimpleErrorHandler()); 

      Builder builder = new Builder(reader); 
      builder.build(new FileInputStream(new File(inputXml))); 

todavía el uso de memoria es muy alto, por xml 15mb - 250mb del montón StackTrace:

Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space 
at java.util.Arrays.copyOf(Arrays.java:2367) 
at java.lang.AbstractStringBuilder.expandCapacity(AbstractStringBuilder.java:130) 
at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:114) 
at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:535) 
at java.lang.StringBuffer.append(StringBuffer.java:322) 
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.handleCharacters(XMLSchemaValidator.java:1574) 
at com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator.characters(XMLSchemaValidator.java:789) 
at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:441) 
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:835) 
at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:764) 
at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:123) 
at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1210) 
at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:568) 
at nu.xom.Builder.build(Unknown Source) 
at nu.xom.Builder.build(Unknown Source) 

EDITAR Mi XML tiene cadena grande base 64

Respuesta

3

Mire este artículo en XML unmarshalling de Marco Tedone see here. Sobre la base de su conclusión de que recomendaría para un bajo consumo de memoria Stax:

XMLInputFactory xmlInputFactory = XMLInputFactory.newInstance(); 
    XMLStreamReader xmlStreamReader = xmlInputFactory.createXMLStreamReader(fileInputStream); 
    Validator validator = schema.newValidator(); 
    validator.validate(new StAXSource(xmlStreamReader)); 
+1

Gracias por su respuesta. Esto todavía usa xerces, así que todavía obtengo OutOfMemory con '-Xmx250m'. Hasta ahora, Woodstox funcionó mejor de mí. – bunnyjesse112

0

Es posible que la memoria está siendo utilizado para el esquema, no el documento de origen. No has dicho nada sobre el esquema. Algunos pueden usar cantidades muy altas de memoria, por ejemplo, si tiene valores finitos grandes de minOccurs o maxOccurs en su modelo de contenido. ¿En qué momento ocurre la excepción de falta de memoria?

+0

Gracias por la respuesta. Xsd tiene cierta cantidad de min/max Ocurre, pero no es tan complicado. Mi xml tiene cadena de base64 y ver fuera de memoria en 'AbstractStringBuilder' – bunnyjesse112

Cuestiones relacionadas