使用Java进行XML动态验证

时间:2013-08-07 13:24:04

标签: java xml validation

基础设施: 我正在使用JAVA 1.5,这是强制性的。但我可以加载任何外部库,所以没问题。

问题:

我有一个通过“外部频道”收集的XML文件,我可以将它用作InputStream

如果有人需要相同,可以使用:

InputStream is = new FileInputStream(file);

我需要针对已经需要XSD的XSD验证XML

<?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获取xsd文件名,XML可能是BIG 1 / 2GB(stax / sax是一个很好的解决方案)

2)我需要从jar加载xsd,因为整个应用程序无法访问文件系统。

对于验证,我更喜欢像http://www.edankert.com/validate.html

这样的系统

我在这个答案中读到了Problem validating an XML file using Java with an XSD having an include

但是使用加载器我无法获得有关文件的信息。

有些想法?

1 个答案:

答案 0 :(得分:2)

  

我有两个主要问题

     

1)我需要从XML获取文件名,XML可能是BIG 1 / 2GB

     

2)我需要从jar加载xsd,因为整个app都不能   访问文件系统。

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

编辑:

  

文件之间的关系是第一个标签i中包含的列表   有要使用的xsd列表,第一个xsd是具有的xsd   与第一个标签相同的名称

<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