2017-01-02 64 views
0

我已經簡單的Spring項目三個模塊分裂,如:XML - 相對路徑XSD

  • 模塊1
    • 的src/main/JAVA/COM /測試/ Module1Test.xml
  • 模塊2
    • 的src /主/ JAVA/COM /測試/ Module2Test.xml
    • 的src/main/JAVA/COM /測試/ Modules.xsd
  • 單詞數
    • 的src/main/JAVA/COM /測試/ Module3Test.xml

你一樣可以在module2中看到我已經創建了XSD文件來驗證所有三個模塊中的XML文件。 要在模塊2驗證XML文件,XSD,我只是簡單地添加以下行:

<?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文件。我不能使用絕對路徑來我的XSD的XML文件,如:

<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"> 

或者其他更好的辦法,只是不使用絕對路徑。

你知道這有可能嗎?我該如何解決它?

+0

你試過'XSI:no​​NamespaceSchemaLocation =「文件:/// C:/項目/模塊2/src目錄/主/ JAVA/COM /測試/ Modules.xsd「'? –

+0

是的,但我不想使用fulll文件路徑到XSD文件的相對路徑 – bontade

回答

1

我認爲「這實際上取決於」,取決於你是如何編碼和你引用的方式,所以我要強調兩個方法:

方法一:通過直接流

您可以直接將XSD作爲輸入流傳遞到您的程序,這樣即使在XML文檔中沒有元素的命名空間時,也不需要依賴「noNamespaceSchemaLocation」屬性。

下面是一個示例程序:

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,你不需要依賴於「noNamespaceSchemaLocation」屬性,因爲你是直接傳遞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命名空間和目標名稱

我會建議你應該使用XML命名空間和目標名稱與XML模式與正確的XML實例。考慮下面的示例XSD和XML。

對於任何人誰不理解XML命名空間和目標名稱的概念,我希望下面的快速分將是有益的:

  • 在XSD,您需要定義「目標名稱」像這樣targetNamespace="http://www.books.org"這沒有什麼,但是你正在爲你的實際XML實例定義命名空間。您需要在您的XML實例中使用相同的名稱空間,即http://www.books.org
  • 在XML實例,您需要:
    • 從XSD製作了「目標名稱」像這樣xmlns="http://www.books.org"
    • 默認的名稱空間,然後使用「的schemaLocation」屬性來告訴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>