【问题标题】:XSD ignoring namespace during validation xsd with importsXSD 在使用导入验证 xsd 期间忽略命名空间
【发布时间】:2020-04-14 07:03:03
【问题描述】:

这个问题我基于简单的例子。 我有 2 个 XSD

ma​​in.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:sub="urn:xsd:subXSD"
           xmlns="urn:xsd:mainXSD"
           targetNamespace="urn:xsd:mainXSD"
           elementFormDefault="qualified">
    <xs:import namespace="urn:xsd:subXSD" schemaLocation="sub.xsd"/>
    <xs:element name="main">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="elementA"/>
                <xs:element maxOccurs="unbounded" name="subElement" type="sub:SubType"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

sub.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns="urn:xsd:subXSD"
           targetNamespace="urn:xsd:subXSD"
           elementFormDefault="qualified">
    <xs:complexType name="SubType">
        <xs:sequence>
            <xs:element name="subA"/>
            <xs:element name="subB"/>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

现在我尝试验证 2 个 xmls

withNamespace.xml

<?xml version="1.0" encoding="UTF-8"?>
<main xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:sub="urn:xsd:subXSD"
      xmlns="urn:xsd:mainXSD"
      xsi:schemaLocation="urn:xsd:mainXSD main.xsd
                   urn:xsd:subXSD sub.xsd">
    <elementA>
        Element A content
    </elementA>
    <subElement>
        <sub:subA>sub 1 a</sub:subA>
        <sub:subB>sub 1 b</sub:subB>
    </subElement>
    <subElement>
        <sub:subA>sub 2 a</sub:subA>
        <sub:subB>sub 2 b</sub:subB>
    </subElement>
</main>

withoutNamespace.xml

<?xml version="1.0" encoding="UTF-8"?>
<main xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns="urn:xsd:mainXSD"
      xsi:schemaLocation="urn:xsd:mainXSD main.xsd">
    <elementA>
        Element A content
    </elementA>
    <subElement>
        <subA>sub 1 a</subA>
        <subB>sub 1 b</subB>
    </subElement>
    <subElement>
        <subA>sub 2 a</subA>
        <subB>sub 2 b</subB>
    </subElement>
</main>

为了验证 xml,我使用了简单的实现:

import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import java.io.File;
import java.io.IOException;

public class XSDExample {

    public static final String BASE_DIR = "...";

    public static void main(String[] args) {
        try {
            SchemaFactory factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
            Schema schema = factory.newSchema(new File(BASE_DIR + "main.xsd"));
            Validator validator = schema.newValidator();
            System.out.println(validate(validator, "withNamespace.xml"));
            System.out.println(validate(validator, "withoutNamespace.xml"));
        } catch (SAXException | IOException e) {
            e.printStackTrace();
        }
    }

    private static String validate(Validator validator, String fileName) throws IOException {
        System.out.println(fileName);
        try {
            validator.reset();
            validator.validate(new StreamSource(new File(BASE_DIR + fileName)));
        } catch (SAXException e) {
            return e.getMessage();
        } catch (IOException e) {
            throw e;
        }
        return "Valid";
    }
}

执行此代码的输出:

withNamespace.xml
Valid
withoutNamespace.xml
cvc-complex-type.2.4.a: Invalid content was found starting with element 'subA'. One of '{"urn:xsd:subXSD":subA}' is expected.

是否可以创建一个 XSD 以允许我验证带有和不带有导入的 XSD 架构命名空间的 XML 文件? 或者也许有 javax.xml.validation.Validator 配置来跳过命名空间检查?

【问题讨论】:

  • &lt;sub:subA&gt;&lt;subA&gt; 是两个不同的元素。与包中名为 Foo 的两个类相同,com.example1com.example2 是两个不同的类。与文件夹 ab 中名为 hello.txt 的两个文件相同,它们是两个不同的文件。 他们不一样,所以他们不应该被同等对待。
  • withoutNamespace.xml 是错误的(命名错误),因为所有元素都有一个命名空间。 xmlns="urn:xsd:mainXSD" 表示任何没有prefix: 的元素都属于命名空间urn:xsd:mainXSD,这意味着&lt;subA&gt;&lt;subB&gt; 在同一个命名空间中。

标签: java xml xsd xsd-validation


【解决方案1】:

可以创建一个允许我验证 XML 的 XSD 带有和不带有导入的 XSD 架构命名空间的文件?

不,没有。

您可以做的是在模式验证之前将两个输入(使用 XSLT)转换为一个通用形式。将标准化转换作为验证管道的第一步是一项非常有价值的技术,但并没有广为人知。

【讨论】:

    猜你喜欢
    • 2012-02-02
    • 2012-06-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-02
    • 1970-01-01
    • 2010-10-29
    • 1970-01-01
    相关资源
    最近更新 更多