2009-10-26 4 views
10

Ho scritto un banale programma scala per aprire un file XML.Come si convalida lo schema di un file XML utilizzando Scala?

C'è un modo per ottenere scala per convalidare il file XML contro il file di schema a cui fa riferimento? Attualmente il mio file XML non segue lo schema, quindi mi aspetterei di ottenere errori durante la convalida.

Il file XML fa riferimento lo schema come questo in l'elemento principale:

<items xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="items.xsd"> 

Il codice Scala:

import scala.xml._ 

object HelloWorld { 
    def main(args: Array[String]) { 
    println("Hello, world! " + args.toList) 

    val start = System.currentTimeMillis 
    val data = XML.loadFile(args(0)) 
    val stop = System.currentTimeMillis 
    Console.println("Took " + (stop-start)/1000.0 + "s to load " + args(0)) 
    } 
} 
HelloWorld.main(args) 

risposta

6

Ecco un post sul blog che descrive come utilizzare le librerie Java per la convalida dello schema a Scala:

http://sean8223.blogspot.com/2009/09/xsd-validation-in-scala.html

si riduce ad una base reimplementazione XML.load:

import javax.xml.parsers.SAXParser 
import javax.xml.parsers.SAXParserFactory 
import javax.xml.validation.Schema 
import javax.xml.validation.ValidatorHandler 
import org.xml.sax.XMLReader 

class SchemaAwareFactoryAdapter(schema:Schema) extends NoBindingFactoryAdapter { 

    override def loadXML(source: InputSource): Elem = { 
    // create parser 
    val parser: SAXParser = try { 
     val f = SAXParserFactory.newInstance() 
     f.setNamespaceAware(true) 
     f.setFeature("http://xml.org/sax/features/namespace-prefixes", true) 
     f.newSAXParser() 
    } catch { 
     case e: Exception => 
     Console.err.println("error: Unable to instantiate parser") 
     throw e 
    } 

    val xr = parser.getXMLReader() 
    val vh = schema.newValidatorHandler() 
    vh.setContentHandler(this) 
    xr.setContentHandler(vh) 

    // parse file 
    scopeStack.push(TopScope) 
    xr.parse(source) 
    scopeStack.pop 
    return rootElem.asInstanceOf[Elem] 
    } 
} 
2

Non credo che si può fare ancora con le librerie Scala. Ma puoi sicuramente usare le librerie Java. Solo Google "convalida dello schema java" e troverete un sacco di opzioni

2

Ecco un adattamento alle variazioni minori API in 2.8.0 (o 2.8.1):

import org.xml.sax.InputSource 
import scala.xml.parsing.NoBindingFactoryAdapter 
import scala.xml.{TopScope, Elem} 
import javax.xml.parsers.{SAXParserFactory, SAXParser} 
import javax.xml.validation.Schema 

class SchemaAwareFactoryAdapter(schema: Schema) extends NoBindingFactoryAdapter { 
    override def loadXML(source: InputSource, parser: SAXParser) = { 
     val reader = parser.getXMLReader() 
     val handler = schema.newValidatorHandler() 
     handler.setContentHandler(this) 
     reader.setContentHandler(handler) 

     scopeStack.push(TopScope) 
     reader.parse(source) 
     scopeStack.pop 
     rootElem.asInstanceOf[Elem] 
    } 

    override def parser: SAXParser = { 
     val factory = SAXParserFactory.newInstance() 
     factory.setNamespaceAware(true) 
     factory.setFeature("http://xml.org/sax/features/namespace-prefixes", true) 
     factory.newSAXParser() 
    } 
} 

L'applicazione è anche leggermente diverso:

val factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI) 
val xsdStream = getClass.getResourceAsStream("/foo.xsd") 
val schema = factory.newSchema(new StreamSource(stream)) 
val source = getClass.getResourceAsStream("baz.xml") 
val xml = new SchemaAwareFactoryAdapter(schema).load(source) 
+0

Questa implementazione ha un enorme perdita di memoria –

Problemi correlati