2013-08-07 57 views
0

基礎結構: 我使用JAVA 1.5,這是強制性的。但我可以加載任何外部庫,所以沒問題。使用Java進行XML動態驗證

問題:

我有一個XML文件,通過「外部通道」 recived,我可以用它爲InputStream的

,如果有人需要得到同樣的,可以使用:

InputStream is = new FileInputStream(file); 

我需要驗證XSD對XSD的內容XSD

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
      xmlns:BODY="urn:CBI:xsd:CBIBdySDDReq.00.00.06" 
      xmlns:HTRT="urn:CBI:xsd:CBIHdrTrt.001.07" 
      xmlns:HE2E="urn:CBI:xsd:CBIHdrSrv.001.07" 
      xmlns:SGNT="urn:CBI:xsd:CBISgnInf.001.04" 
      xmlns:LMSG="urn:CBI:xsd:CBISDDReqLogMsg.00.00.06" 
      xmlns="urn:CBI:xsd:CBISDDReqPhyMsg.00.00.06" 
      targetNamespace="urn:CBI:xsd:CBISDDReqPhyMsg.00.00.06" 
      elementFormDefault="qualified"> 
    <xs:import namespace="urn:CBI:xsd:CBIHdrTrt.001.07" schemaLocation="CBIHdrTrt.001.07.xsd"/> 
    <xs:import namespace="urn:CBI:xsd:CBIHdrSrv.001.07" schemaLocation="CBIHdrSrv.001.07.xsd"/> 
    <xs:import namespace="urn:CBI:xsd:CBIBdySDDReq.00.00.06" schemaLocation="CBIBdySDDReq.00.00.06.xsd"/> 
    <xs:element name="CBISDDReqPhyMsg" type="CBISDDReqPhyMsg.00.00.06"> 
     <xs:annotation> 
      <xs:documentation>1. - Tag root dell'intero messaggio fisico di richiesta SDD CBI</xs:documentation> 
     </xs:annotation> 
    </xs:element> 
    <xs:complexType name="CBISDDReqPhyMsg.00.00.06"> 
     <xs:sequence> 
      <xs:element name="CBIHdrTrt" type="HTRT:CBIHdrTrt.001.07"> 
       <xs:annotation> 
        <xs:documentation>1.1. - Header di tratta CBI</xs:documentation> 
       </xs:annotation> 
      </xs:element> 
      <xs:element name="CBIHdrSrv" type="HE2E:CBIHdrSrv.001.07"> 
       <xs:annotation> 
        <xs:documentation>1.2. - Header di servizio CBI</xs:documentation> 
       </xs:annotation> 
      </xs:element> 
      <xs:element name="CBIBdySDDReq" type="BODY:CBIBdySDDReq.00.00.06"> 
       <xs:annotation> 
        <xs:documentation>1.3. - Body di servizio CBI</xs:documentation> 
       </xs:annotation> 
      </xs:element> 
     </xs:sequence> 
    </xs:complexType> 
</xs:schema> 

所以我有一個XSD文件早午餐。

一大塊XML文件是這樣的

<?xml version="1.0" encoding="UTF-8"?> 
<MSG:CBISDDReqPhyMsg xmlns:MSG="urn:CBI:xsd:CBISDDReqPhyMsg.00.00.06" 
    xmlns:HTRT="urn:CBI:xsd:CBIHdrTrt.001.07" xmlns:HE2E="urn:CBI:xsd:CBIHdrSrv.001.07" 
    xmlns:BODY="urn:CBI:xsd:CBIBdySDDReq.00.00.06" xmlns:LMSG="urn:CBI:xsd:CBISDDReqLogMsg.00.00.06" 
    xmlns:SGNT="urn:CBI:xsd:CBISgnInf.001.04" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <MSG:CBIHdrTrt> 
     <HTRT:IdCBISndrf>0000636J</HTRT:IdCBISndrf> 
     <HTRT:IdCBIRcvrf>0000641V</HTRT:IdCBIRcvrf> 
     <HTRT:SrvNm>INC-SDDC</HTRT:SrvNm> 
     <HTRT:IdMsgTrt> 
      0000636JP12312111154007381042010010000636J000000636J0000641V0 
     </HTRT:IdMsgTrt> 

,所以我需要驗證對CBISDDReqPhyMsg.00.00.06的XML。所以我只知道在運行時反對偉大的XML使用。例如另一個文件可以加載CBISDDReqPhyMsg.00.00.05

我有兩個主要問題

1)我需要從XML和XML獲得XSD文件名可能是BIG 1/2GB(STAX /薩克斯是一個很好的解決方案)

2)我需要從jar中加載xsd,因爲整個應用程序無法訪問文件系統。

爲了驗證我喜歡像http://www.edankert.com/validate.html

系統我讀到包括在這個答案Problem validating an XML file using Java with an XSD having an include

但是用裝載機我無法獲取有關文件的相關信息。

有些想法?

+0

關於#1:XML文檔本身沒有文件名 - 這又如何涉及到的文件大小? – home

+0

我需要獲得的xsd文件名稱和文件的大小是我不能使用DOM這兩個句子是相關的信息,我無法加載整個文件和稍後搜索文件中的大小。 – user1594895

+0

@ user1594895在XSD文件名和XML中的數據之間是否有模式?我見過許多情況下沒有模式... –

回答

2

我有兩個主要問題

1)我需要從XML和XML獲取文件名可能是BIG 1/2GB

2)我需要從一個罐子,因爲加載XSD整個應用程序不能有 訪問文件系統。

1.)文件名不在XML內部......您應該通過其他方式(用戶輸入,硬編碼等)知道XML的文件名是什麼。如果你有一個只有XML文件的目錄,你可以在文件上運行一個循環。一些僞代碼:

for(getNextFile) 
{ 
    if(xmlValidationWithXSD(nextFile)) 
     //passed validation 
    else 
     //failed validation 
} 

我通常運行腳本將所有XML文件從一個位置移動到純XML文件夾。

2.)我相信StreamSource可以讓你做到這一點。這是我最近所做的:

  public static boolean xmlValidationWithXSD(String xmlLocation){ 
       Source xmlFile = new StreamSource(new File(xmlLocation)); 

       //IMPORTANT: Here is what you need. Multiple XSDs (that relate to each other) AND getResource will access form .jar files 
       //Treat XSD as resource found in the class path, assume that the full package name is passed in xsdLocation 
       Source schemaFileSource1 = new StreamSource(BenefitEnrollmentRequestFileUtil.class.getResource(NEW_XSD_FILE_RESOURCE1).toString()); 
       Source schemaFileSource2 = new StreamSource(BenefitEnrollmentRequestFileUtil.class.getResource(NEW_XSD_FILE_RESOURCE2).toString()); 
       Source[] schemaFileSources = {schemaFileSource1, schemaFileSource2}; 


       SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 

       try { 
        Schema schema = schemaFactory.newSchema(schemaFileSources); 
        Validator validator = schema.newValidator(); 
        validator.validate(xmlFile); 
        return true; 
       } catch (SAXException e) { 
        LOGGER.debug(xmlFile.getSystemId() + " is NOT valid", e); 
        LOGGER.debug("Reason: " + e.getLocalizedMessage()); 
       } catch (IOException e) { 
        LOGGER.debug(xmlFile.getSystemId() + " is NOT valid", e); 
        LOGGER.debug("Reason: " + e.getLocalizedMessage());     
       } 
       return false; 
      } 

來源:

Referencing a XSD schema within jar file

Problem validating an XML file using Java with an XSD having an include

編輯:

文件之間的關係是包含在第一個標籤我的列表 有要使用的xsd列表和第一個XSD是具有 相同namesace作爲第一個標籤

<MSG:CBISDDReqPhyMsg xmlns:MSG="urn:CBI:xsd:CBISDDReqPhyMsg.00.00.06" xmlns:HTRT="urn:CBI:xsd:CBIHdrTrt.001.07" xmlns:HE2E="urn:CBI:xsd:CBIHdrSrv.001.07" xmlns:BODY="urn:CBI:xsd:CBIBdySDDReq.00.00.06" xmlns:LMSG="urn:CBI:xsd:CBISDDReqLogMsg.00.00.06" xmlns:SGNT="urn:CBI:xsd:CBISgnInf.001.04" xmlns:xsi="w3.org/2001/XMLSchema-instance">; 

你能不能讀這行頭,然後提取的數據嗎?使用FileReader/DOM(如果你只讀一行,它不應該太慢)才能檢索這一行。然後通過String解析。創建一個ArrayList並添加您提取的每個單獨的片段。

檢查了這一點,只要效率會:

https://stackoverflow.com/a/2134533/2498729

https://stackoverflow.com/a/12273296/2498729

+0

我已更正了我的qyuestion中第一點的不明確性,其中包含XSD的文件名 – user1594895