2009-10-26 13 views
10

Napisałem trywialny program scala, aby otworzyć plik XML.W jaki sposób można sprawdzić poprawność schematu pliku XML za pomocą Scala?

Czy istnieje sposób, aby uzyskać scala do sprawdzania poprawności pliku XML względem pliku schematu, który się odwołuje? Obecnie mój plik XML nie jest zgodny ze schematem, więc spodziewałbym się uzyskać błędy w sprawdzaniu poprawności.

Plik XML odwołuje się do schematu jak to w elemencie głównym:

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

Kod 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) 

Odpowiedz

6

Oto blogu opisujące sposób korzystania z bibliotek Java dla sprawdzania schematu w Scala:

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

Sprowadza do podstawowego ponownego wykonania 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

Nie sądzę, można to zrobić jeszcze z bibliotekami Scala. Ale zdecydowanie możesz korzystać z bibliotek Java. Tylko google „poprawności schematu java”, a znajdziesz wiele opcji

2

Tutaj jest adaptacją do niewielkich zmian API w 2.8.0 (lub 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() 
    } 
} 

Aplikacja jest również nieco inna:

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

Ta implementacja ma ogromny wyciek pamięci –

Powiązane problemy