Как проверить XML с XSD внутри? - PullRequest
1 голос
/ 01 февраля 2012

У меня проблемы с проверкой xml-файла по xml-схеме в случае, если xml-документ содержит схему. XML-файл выглядит так:

<?xml version="1.0"?>
<catalog xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
         xmlns:x="urn:book"> 
<!-- START OF SCHEMA -->
<xsd:schema targetNamespace="urn:book">
 <xsd:element name="book">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="author" type="xsd:string"/>
      <xsd:element name="title" type="xsd:string"/>
      <xsd:element name="genre" type="xsd:string"/>
      <xsd:element name="price" type="xsd:float"/>
      <xsd:element name="publish_date" type="xsd:date"/>
      <xsd:element name="description" type="xsd:string"/>
    </xsd:sequence>
    <xsd:attribute name="id" type="xsd:string"/>
  </xsd:complexType>
 </xsd:element>
</xsd:schema>
<!-- END OF SCHEMA -->
   <x:book id="bk101">
      <author>Gambardella, Matthew</author>
      <title>XML Developer's Guide</title>
      <genre>Computer</genre>
      <price>44.95</price>
      <publish_date>2000-10-01</publish_date>
      <description>An in-depth look at creating applications with
      XML.</description>
   </x:book>
</catalog>

Java-код выглядит так:

// define the type of schema - we use W3C:
String schemaLang = "http://www.w3.org/2001/XMLSchema";

// get validation driver:
SchemaFactory factory = SchemaFactory.newInstance(schemaLang);

// create schema by reading it from an XSD file:
Schema schema = factory.newSchema(new StreamSource("..........."));
Validator validator = schema.newValidator();

// at last perform validation:
validator.validate(new StreamSource("myDoc.xml"));

И проблема для меня в том, как использовать объект SchemaFactory в этом случае?

Я очень благодарен за любую помощь!

Ответы [ 2 ]

2 голосов
/ 02 февраля 2012

Я полагаю, это то, что вы хотите;код предназначен для иллюстрации, а не для учета хороших практик программирования.Это было проверено с вашим XML.Основное предположение состоит в том, что элемент документа имеет два элемента: первый - XSD, второй - XML ​​для проверки.

Если, например, вы измените 44,95 на d44,95, вы получите такой вывод:

XML недопустим, поскольку cvc-datatype-valid.1.2.1: «d44.95» не является допустимым значением для «float».

В противном случае все идет хорошои программа печатает XML действителен.

import java.io.*;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.validation.*;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import javax.xml.xpath.*;
import org.xml.sax.InputSource;

public class TestValidation {
    public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException, XPathExpressionException {
        XPath xpath = XPathFactory.newInstance().newXPath();
        NodeList nodes = (NodeList)xpath.evaluate("/*/*", new InputSource("XmlWithEmbeddedXsd.xml"), XPathConstants.NODESET);
        SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
        Validator validator = factory.newSchema(new DOMSource(nodes.item(0))).newValidator();
        try {
            validator.validate(new DOMSource(nodes.item(1)));
            System.out.println("XML is valid.");
        }
        catch (SAXException ex) {
            System.out.println("XML is not valid because " + ex.getMessage());
        }
    }
}
0 голосов
/ 02 февраля 2012

В качестве альтернативы решению Gardea (что хорошо, за исключением того, что у меня есть отвращение ко всему, что связано с использованием DOM), вы можете выполнить преобразование, чтобы извлечь схему и элемент книги как отдельные документы, прежде чем проверять один против другого,Я упоминаю об этом, потому что преобразование перед проверкой является недоиспользуемым шаблоном проектирования.

...