2012-02-01 12 views
5

Jak można sprawdzić poprawność pliku XML za pomocą XSD w Javie? Nie znamy schematu z góry. Chciałbym móc uzyskać schemaLocation, pobrać XSD, buforować go, a następnie wykonać faktyczną walidację.Sprawdzanie poprawności kodu XML względem XSD w języku Java/Uzyskiwanie blokady schematuLocation

Problem polega na tym, że przy klasach javax.xml.parsers.DocumentBuilder/DocumentBuilderFactory nie mogę wydawać się wcześniej w stanie uzyskać blokady schemaLocation. Jaka jest tego sztuczka? Na które zajęcia powinienem zajrzeć?

Być może istnieje lepszy interfejs API, którego mogę użyć? Cały problem polega na tym, że musimy sprawdzać poprawność dynamicznie, bez (koniecznie) posiadania lokalnie XSD.

Jak można uzyskać adres URL z schemaLocation zdefiniowany w pliku XSD?

Wiem, że można ustawić funkcje/atrybuty, ale to zupełnie co innego. Najpierw muszę pobrać schemaLocation z XSD.

Proszę doradzić!

Odpowiedz

4

Biorąc pod uwagę, że używasz Xerces (lub domyślnego JDK), czy próbowałeś ustawić tę funkcję na fabrykę: http://apache.org/xml/features/validation/schema. Istnieją inne funkcje, które można odtwarzać w zakresie schematów: http://xerces.apache.org/xerces2-j/features.html

UPDATE 2 (dla buforowania):

Wdrożenie org.w3c.dom.ls.LSResourceResolver i ustawić to na SchemaFactory stosując metodę setResourceResolver. Ten resolver albo pobiera schemat z pamięci podręcznej, albo pobiera go z dowolnego miejsca, do którego się odnosi.

UPDATE 3:

LSResourceresolver przykład (co moim zdaniem będzie to dobry punkt wyjścia dla Ciebie):

/** 
* Resolves resources from a base URL 
*/ 
public class URLBasedResourceResolver implements LSResourceResolver { 

private static final Logger log = LoggerFactory 
     .getLogger(URLBasedResourceResolver.class); 

private final URI base; 

private final Map<URI, String> nsmap; 

public URLBasedResourceResolver(URL base, Map<URI, String> nsmap) 
     throws URISyntaxException { 
    super(); 
    this.base = base.toURI(); 
    this.nsmap = nsmap; 
} 

@Override 
public LSInput resolveResource(String type, String namespaceURI, 
     String publicId, String systemId, String baseURI) { 
    if (log.isDebugEnabled()) { 
     String msg = String 
       .format("Resolve: type=%s, ns=%s, publicId=%s, systemId=%s, baseUri=%s.", 
         type, namespaceURI, publicId, systemId, baseURI); 
     log.debug(msg); 
    } 
    if (type.equals(XMLConstants.W3C_XML_SCHEMA_NS_URI)) { 
     if (namespaceURI != null) { 
      try { 
       URI ns = new URI(namespaceURI); 
       if (nsmap.containsKey(ns)) 
        return new MyLSInput(base.resolve(nsmap.get(ns))); 
      } catch (URISyntaxException e) { 
       // ok 
      } 
     } 
    } 
    return null; 
} 

} 

Realizacja MyLSInput jest bardzo nudne:

class MyLSInput implements LSInput { 

private final URI url; 

public MyLSInput(URI url) { 
    super(); 
    this.url = url; 
} 

@Override 
public Reader getCharacterStream() { 
    return null; 
} 

@Override 
public void setCharacterStream(Reader characterStream) { 

} 

@Override 
public InputStream getByteStream() { 
    return null; 
} 

@Override 
public void setByteStream(InputStream byteStream) { 

} 

@Override 
public String getStringData() { 
    return null; 
} 

@Override 
public void setStringData(String stringData) { 

} 

@Override 
public String getSystemId() { 
    return url.toASCIIString(); 
} 

@Override 
public void setSystemId(String systemId) { 
} 

@Override 
public String getPublicId() { 
    return null; 
} 

@Override 
public void setPublicId(String publicId) { 
} 

@Override 
public String getBaseURI() { 
    return null; 
} 

@Override 
public void setBaseURI(String baseURI) { 

} 

@Override 
public String getEncoding() { 
    return null; 
} 

@Override 
public void setEncoding(String encoding) { 

} 

@Override 
public boolean getCertifiedText() { 
    return false; 
} 

@Override 
public void setCertifiedText(boolean certifiedText) { 

} 

} 
+0

dotycząca pierwszy link - używam xerces: 2.10.0 jako autonomicznej zależności Maven poza JDK. Drugi link nie działa. Nie mam nic przeciwko używaniu innego API razem. – carlspring

+0

@ carlspring. Zobacz aktualizację. –

+0

Tak, chociaż jest to rzeczywiście poprawne, nadal nie mam położenia schematu, dlatego nie mogę tego buforować i muszę zaimplementować buforowanie. Dlatego naprawdę potrzebuję najpierw uzyskać '' schemaLocation'. – carlspring

Powiązane problemy