XML - XSD的相对路径

时间:2017-01-02 20:42:09

标签: java xml xsd

我有简单的Spring项目分为三个模块,如:

  • 模块1
    • 的src /主/ JAVA / COM /测试/ Module1Test.xml
  • 模块2
    • 的src /主/ JAVA / COM /测试/ Module2Test.xml
    • 的src /主/ JAVA / COM /测试/ Modules.xsd
  • 单词数
    • 的src /主/ JAVA / COM /测试/ Module3Test.xml

就像你在module2中看到的那样,我创建了XSD文件来验证所有三个模块中的XML文件。 要在module2中使用XSD验证XML文件,我只需添加以下行:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<Module2Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="Modules.xsd">

但我不知道如何使用XSD验证Module1Test.xmlModule3Test.xml个文件。我不能在XML文件中使用绝对路径到我的XSD,如:

<Module2Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///C:\\project\\module2\\src\\main\\java\\com\\test\\Modules.xsd">

我想使用相对路径,例如:

<Module2Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project\\module2\\src\\main\\java\\com\\test\\Modules.xsd">

或者以其他更好的方式,只是为了不使用绝对路径。

你知道这是否可能?我该如何解决?

1 个答案:

答案 0 :(得分:1)

我认为&#34; 真的取决于&#34;,取决于您的编码方式和引用方式,所以我要强调两种方法:

方法#1:作为直接流传递

您可以直接将XSD作为输入流传递给您的程序,这样您就不必依赖于&#34; noNamespaceSchemaLocation&#34;即使XML文档中的元素没有名称空间,也要归属。

以下是示例程序:

import org.w3c.dom.Document; 
import org.xml.sax.SAXException; 
import org.xml.sax.SAXParseException; 
import org.xml.sax.InputSource; 


import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.StringReader; 


import javax.xml.XMLConstants; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.parsers.ParserConfigurationException; 
import javax.xml.transform.Source; 

import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamSource; 
import javax.xml.validation.Schema; 
import javax.xml.validation.SchemaFactory; 
import javax.xml.validation.Validator; 

public class XmlSchemaValidationHelper { 

    public static void main(String[] argv) {
        XmlSchemaValidationHelper schemaValidationHelper = new XmlSchemaValidationHelper();
        schemaValidationHelper.validateAgainstSchema(new File(argv[0]), new File(argv[1]));
    }

    public void validateAgainstSchema(File xmlFile, File xsdFile) { 
        try {
            System.out.println("### Starting...");
            // parse an XML document into a DOM tree 
            DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); 
            builderFactory.setNamespaceAware(true); 
            DocumentBuilder parser = builderFactory.newDocumentBuilder(); 
            Document document = parser.parse(xmlFile); 

            // create a SchemaFactory capable of understanding WXS schemas 
            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 

            // load a WXS schema, represented by a Schema instance 
            Source schemaFile = new StreamSource(xsdFile); 
            Schema schema = factory.newSchema(schemaFile); 

            // create a Validator instance, which can be used to validate an 
            // instance document 
            Validator validator = schema.newValidator(); 

            // validate the DOM tree 
            validator.validate(new DOMSource(document));
            System.out.println("### Finished...");

        } catch (FileNotFoundException ex) { 
            throw new OpenClinicaSystemException("File was not found", ex.getCause()); 
        } catch (IOException ioe) { 
            throw new OpenClinicaSystemException("IO Exception", ioe.getCause()); 
        } catch (SAXParseException spe) { 
            spe.printStackTrace(); 
            throw new OpenClinicaSystemException("Line : " + spe.getLineNumber() + " - " + spe.getMessage(), spe.getCause()); 
        } catch (SAXException e) { 
            throw new OpenClinicaSystemException(e.getMessage(), e.getCause()); 
        } catch (ParserConfigurationException pce) { 
            throw new OpenClinicaSystemException(pce.getMessage(), pce.getCause()); 
        } 
    } 

    public class OpenClinicaSystemException extends RuntimeException { 
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private String errorCode; 
        private Object[] errorParams; 

        public OpenClinicaSystemException(String code, String message) { 
            this(message); 
            this.errorCode = code; 
        } 

        public OpenClinicaSystemException(String code, String message, Throwable cause) { 
            this(message, cause); 
            this.errorCode = code; 
        } 

        public OpenClinicaSystemException(String message, Throwable cause) { 
            super(message, cause); 
        } 

        public OpenClinicaSystemException(Throwable cause) { 
            super(cause); 
        } 

        public OpenClinicaSystemException(String message) { 
            super(message); 
            this.errorCode = message; 
        } 

        public OpenClinicaSystemException(String code, Object[] errorParams) { 
            this.errorCode = code; 
            this.errorParams = errorParams; 
        } 

        public OpenClinicaSystemException(String code, Object[] errorParams, String message) { 
            this(message); 
            this.errorCode = code; 
            this.errorParams = errorParams; 
        } 

        public String getErrorCode() { 
            return errorCode; 
        } 

        public Object[] getErrorParams() { 
            return errorParams; 
        } 

        public void setErrorParams(Object[] errorParams) { 
            this.errorParams = errorParams; 
        } 
    }

}

像这样运行:E:\xmlValidator>java XmlSchemaValidationHelper po.xml test/po.xsd并且您不需要依赖&#34; noNamespaceSchemaLocation&#34;属性,因为您直接将XSD作为输入流传递给验证器/解析器。

这是根据XSD验证XML的快捷方式

方法#2:正确退出XSD路径

您只需要正确地转义XSD路径,因此请改用以下任一方式:

<Module2Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="file:///C://project//module2//src//main//java//com//test//Modules.xsd">

OR

<Module2Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="C://project//module2//src//main//java//com//test//Modules.xsd">

请阅读MSDN official article相同内容。

最后的话:使用XML名称空间和targetNamespace

我建议你使用XML命名空间和targetNamespace 来正确地将XML实例与XML模式相关联。请考虑以下示例XSD和XML。

对于那些不了解XML命名空间和targetNamespace概念的人,我希望以下快点可能会有所帮助:

  • 在XSD中,您需要定义&#34; targetNamespace&#34;就像这个targetNamespace="http://www.books.org"一样,你只是在为实际的XML实例定义命名空间。您需要在XML实例中使用相同的命名空间,即http://www.books.org
  • 在XML实例中,您需要:
    • 制作&#34; targetNamespace&#34;从XSD作为默认命名空间,如xmlns="http://www.books.org"
    • 然后使用&#34; schemaLocation&#34;属性告诉XML验证器XML模式中应该是什么目标命名空间,验证器将适当地解析URI xsi:schemaLocation="http://www.books.org"

示例XML:

<?xml version="1.0"?>
<BookStore xmlns="http://www.books.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.books.org">
        <Book>
                <Title>My Life and Times</Title>
                <Author>Paul McCartney</Author>
                <Date>1998</Date>
                <ISBN>1-56592-235-2</ISBN>
                <Publisher>McMillin Publishing</Publisher>
        </Book>
        <Book>
                <Title>Illusions The Adventures of a Reluctant Messiah</Title>
                <Author>Richard Bach</Author>
                <Date>1977</Date>
                <ISBN>0-440-34319-4</ISBN>
                <Publisher>Dell Publishing Co.</Publisher>
        </Book>
        <Book>
                <Title>The First and Last Freedom</Title>
                <Author>J. Krishnamurti</Author>
                <Date>1954</Date>
                <ISBN>0-06-064831-7</ISBN>
                <Publisher>Harper &amp; Row</Publisher>
        </Book>
</BookStore>

示例XSD:

<?xml version="1.0"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
            targetNamespace="http://www.books.org"
            xmlns="http://www.books.org"
            elementFormDefault="qualified">
    <xsd:simpleType name="ISBN-type">
        <xsd:restriction base="xsd:string">
            <xsd:pattern value="\d{1}-\d{5}-\d{3}-\d{1}|\d{1}-\d{3}-\d{5}-\d{1}|\d{1}-\d{2}-\d{6}-\d{1}"/>
        </xsd:restriction>
    </xsd:simpleType>
    <xsd:element name="BookStore">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="Book" maxOccurs="unbounded">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="Title" type="xsd:string"/>
                            <xsd:element name="Author" type="xsd:string"/>
                            <xsd:element name="Date" type="xsd:gYear"/>
                            <xsd:element name="ISBN" type="ISBN-type"/>
                            <xsd:element name="Publisher" type="xsd:string"/>
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>