2012-03-20 20 views
5

メモリの使用でbig xmlを検証する必要があります。私が今までに見つけたすべてのコードで、私はメモリエラーから抜け出す。xsdスキーマに対してbig xmlを検証する方法は?

方法は、私が試した:

//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(); 

//方法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); 

私は毎回のOutOfMemory取得

EDIT 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))); 

まだメモリ使用量が15メガバイトのXMLのために、非常に高いです - ヒープの250メガバイト スタックトレース:

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) 

EDIT 私のXMLは、大きなbase64文字列

答えて

3

Marco TedoneのXMLアンマーシャリングに関するこの記事をご覧ください。see here彼の結論に基づいて 私が低メモリ消費スタックスのために推薦する:応答のための

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

応答してくれてありがとう。これはまだxercesを使用しているので、 '-Xmx250m'でOutOfMemoryを取得します。これまでのところ、木材は私から一番うまくいった。 – bunnyjesse112

0

を持っていることは、メモリがされている可能性がありますソース文書ではなくスキーマに使用されます。あなたはスキーマについて何も言わなかった。たとえば、コンテンツモデルにminOccursまたはmaxOccursという有限の値がある場合など、非常に大量のメモリを使用するものもあります。どの時点でメモリ不足例外が発生しますか?

+0

感謝を。 Xsdには最小/最大量がありますが、複雑ではありません。私のXMLはbase64の文字列を持ち、 'AbstractStringBuilder'でoutofmemoryを参照してください – bunnyjesse112

関連する問題