代码之家  ›  专栏  ›  技术社区  ›  Simon

Java:针对包含另一个xsd的xsd的字符串xml验证

  •  1
  • Simon  · 技术社区  · 7 年前

    更新1:New Validation method抛出新错误,请参见下文。

    希望有人知道我错在哪里。

    我目前正在尝试根据包含另一个xsd的xsd验证xml文件。我不知道我的XSD或java代码是否有故障。我没有存储xml/xsd文件,而是将它们作为base64字符串从服务器获取。希望有人能帮忙。

    org.xml.sax.SAXParseException; lineNumber: 81; columnNumber: 104; src-resolve: Cannot resolve the name 'ServiceSpecificationSchema:ServiceIdentifier' to a(n) 'type definition' component.
    

    -ServiceSpecificationSchema。xsd

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ServiceSpecificationSchema="http://example.org/ServiceSpecificationSchema.xsd" targetNamespace="http://example.org/ServiceSpecificationSchema.xsd" version="1.0" xml:lang="EN">
    
        <include schemaLocation="ServiceBaseTypesSchema.xsd"/>
        <element name="serviceSpecification" type="ServiceSpecificationSchema:ServiceSpecification">
            <unique name="serviceDataModelTypeKey">
                <selector xpath=".//xs:*"/>
                <field xpath="@name"/>
            </unique>
            <keyref name="serviceDataModelReturnValueTypeKeyRef" refer="ServiceSpecificationSchema:serviceDataModelTypeKey">
                <selector xpath=".//ServiceSpecificationSchema:returnValueType"/>
                <field xpath="ServiceSpecificationSchema:typeReference"/>
            </keyref>
            <keyref name="serviceDataModelParameterTypeTypeKeyRef" refer="ServiceSpecificationSchema:serviceDataModelTypeKey">
                <selector xpath=".//ServiceSpecificationSchema:parameterType"/>
                <field xpath="ServiceSpecificationSchema:typeReference"/>
            </keyref>
        </element>
        <complexType name="ServiceSpecification">
            <all>
                <element name="id" type="ServiceSpecificationSchema:ServiceIdentifier" minOccurs="1" maxOccurs="1"/>
    .....
    

    ServiceBaseTypeSchema:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ServiceSpecificationSchema="http://example.org/ServiceSpecificationSchema.xsd" targetNamespace="http://example/ServiceSpecificationSchema.xsd" version="1.0" xml:lang="EN">
    ...
        <simpleType name="ServiceIdentifier">
            <restriction base="string"/>
        </simpleType>
    ...
    </schema>
    

    Java验证器

    public void validate(String inputXml, String XSD, String XSD2)
            throws SAXException, IOException {
            try {
                byte[] decoded = Base64.decodeBase64(XSD);
                XSD = new String(decoded, "UTF-8");
                byte[] decoded2 = Base64.decodeBase64(XSD2);
                XSD2 = new String(decoded2, "UTF-8");
    
            SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
    
            Schema schema = factory.newSchema(new SAXSource[]
            {
            (new SAXSource(new InputSource(new StringReader(XSD)))),
            (new SAXSource(new InputSource(new StringReader(XSD2))))
            });
    
            Validator validator = schema.newValidator();
            validator.validate(new StreamSource(new StringReader(inputXml)));
            } catch (SAXException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
            }
    
    }
    

    我找到了另一个可能的解决方案,但仍然不起作用。使用以下方法,抛出exeption,根据xml验证XSD。例外行取决于使用的xml。在底部的示例中,错误在第2行-&燃气轮机;错误: 找不到元素“ServiceSpecificationSchema:serviceSpecification”的声明

    新Java验证器:

    byte[] decoded = Base64.decodeBase64(XSD);
                    byte[] decoded2 = Base64.decodeBase64(XSD2);
    
                    SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
    
                    InputStream impFis = new ByteArrayInputStream(decoded2);
                    InputStream mainFis = new ByteArrayInputStream(decoded);
    
                    Source main = new StreamSource(mainFis);
                    Source imp = new StreamSource(impFis);
                    Source[] schemaFiles = new Source[] {imp, main};
                    Schema schema = factory.newSchema(schemaFiles);
                    Validator validator = schema.newValidator();
                    validator.validate(new StreamSource(new StringReader(inputXml))); 
    

    XML文件示例:

    <?xml version="1.0" encoding="UTF-8"?>
    <ServiceSpecificationSchema:serviceSpecification
            xmlns:ServiceSpecificationSchema="http://example.org/ServiceSpecificationSchema.xsd"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://example.org/ServiceSpecificationSchema.xsd">
    .....
    
    1 回复  |  直到 7 年前
        1
  •  0
  •   Simon    7 年前

    这对我来说很有用:

    @Service
    public class ResourceResolverImpl implements LSResourceResolver {
    private ILoadFromSRService iLoadFromSRService;
    
    @Autowired
    public ResourceResolverImpl(ILoadFromSRService iLoadFromSRService){
        this.iLoadFromSRService = iLoadFromSRService;
    }
    
    public LSInput resolveResource(String type,
                                   String namespaceURI,
                                   String publicId,
                                   String systemId,
                                   String baseURI) {
        String string =iLoadFromSRService.getServiceBaseTypeSchema();
        string = string.replace("\n", "").replace("\t", "");
        InputStream resourceAsStream = new ByteArrayInputStream( string.getBytes());
        return new LSInputImpl(publicId, systemId, resourceAsStream);
        }
    }