假设我有一个XML文档(表示为文本,W3C DOM,无论如何),还有一个XML Schema.XML文档具有模式定义的所有正确元素,但顺序错误.
如何使用模式"重新排序"文档中的元素以符合模式定义的顺序?
我知道这应该是可能的,可能使用XSOM,因为JAXB XJC代码生成器使用元素的正确序列化顺序来注释其生成的类.
但是,我不熟悉XSOM API,它非常密集,所以我希望你们中的一个人有一些经验,可以指出我正确的方向.像"在这个父元素中允许哪些子元素,以什么顺序?"之类的东西.
让我举个例子.
我有一个像这样的XML文档:
<A>
<Y/>
<X/>
</A>
Run Code Online (Sandbox Code Playgroud)
我有一个XML Schema,它说<A>必须是一个<X>后跟a的内容<Y>.现在显然,如果我尝试根据模式验证文档,它会失败,因为<X>并且<Y>顺序错误.但我知道我的文档提前是"错误的",所以我还没有使用模式进行验证.不过,我不知道,我的文档具有所有正确的元素由模式只是在错误的顺序定义.
我想要做的是以编程方式检查Schema(可能使用XSOM - 这是XML Schema的对象模型),并询问它<A>应该是什么内容.API将公开"您需要<X>后跟a <Y>"的信息.
所以我使用我的XML文档(使用DOM API)并相应地重新安排,以便现在文档将根据模式进行验证.
了解XSOM在这里是什么很重要 - 它是一个java API,它表示XML Schema中包含的信息,而不是我的实例文档中包含的信息.
我不想做的是从架构生成代码,因为架构在构建时是未知的.此外,XSLT没有用,因为元素的正确排序仅由模式中包含的数据字典决定.
希望现在已经足够明确了.
我在Java中使用XSOM进行了很多难以解析的.XSD文件.我有两个.XSD文件,一个定义日历,第二个定义全局类型.我希望能够阅读日历文件并确定:
日历有3个属性
Calendar.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:gtypes="http://www.btec.com/gtypes"
elementFormDefault="qualified">
<xs:import namespace="http://www.btec.com/gtypes"
schemaLocation="gtypes.xsd"/>
<xs:element name="CALENDAR">
<xs:complexType>
<xs:sequence>
<xs:element name="Valid" type="eYN" minOccurs="0"/>
<xs:element name="Cal" minOccurs="0">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="gtypes:STRING">
<xs:attribute name="IsKey" type="xs:string" fixed="Y"/>
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:element name="Status" type="eSTATUS" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="eSTATUS">
<xs:simpleContent>
<xs:extension base="gtypes:ENUM"/>
</xs:simpleContent>
</xs:complexType>
<xs:complexType name="eYN">
<xs:simpleContent>
<xs:extension base="gtypes:ENUM"/>
</xs:simpleContent>
</xs:complexType>
Run Code Online (Sandbox Code Playgroud)
gtypes.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.btec.com/gtypes"
elementFormDefault="qualified">
<xs:complexType name="ENUM">
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="TYPE" fixed="ENUM"/>
<xs:attribute name="derived" use="optional"/>
<xs:attribute …Run Code Online (Sandbox Code Playgroud) 我需要解析一个XSD,XSOM但这个XSD包含循环导入.
A.xsd
<xs:schema xmlns=”ns1” targetNamespace=”ns1”>
<xs:import namespace=”ns2” schemaLocation=”B.xsd”/>
<xs:element name=”MyElement” type=”xs:string”/>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
B.xsd
<xs:schema xmlns=”ns2” targetNamespace=”ns2” xmlns:ns1=”ns1”>
<xs:import namespace=”ns1” schemaLocation=”A.xsd”/>
<xs:complexType name="MyComplex">
<xs:sequence>
<xs:element ref="ns1:MyElement" minOccurs="0"/>
<xs:sequence>
<xs:complexType>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
XSOM无法解析模式,因为它检测到由于循环导入而已定义的元素.所以我试图通过外化由A定义并在B中使用的元素来打破循环导入.
C.xsd包含A使用的元素B.请注意,这些元素不在A中使用.不要问我为什么在A中定义了这些元素.
<xs:schema xmlns=”ns1” targetNamespace=”ns1”>
<xs:element name=”MyElement” type=”xs:string”/>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
A.xsd成了
<xs:schema xmlns=”ns1” targetNamespace=”ns1”>
<xs:import namespace=”ns2” schemaLocation=”B.xsd”/>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
B.xsd(导入C.xsd而不是A.xsd)成为
<xs:schema xmlns=”ns2” targetNamespace=”ns2” xmlns:ns1=”ns1”>
<xs:import namespace=”ns1” schemaLocation=”C.xsd”/>
<xs:complexType name="MyComplex">
<xs:sequence>
<xs:element ref="ns1:MyElement" minOccurs="0"/>
<xs:sequence>
<xs:complexType>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)
XSOM可以解析XSD.但现在我无法使用以下代码创建架构:
SchemaFactory sf = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
sf.setResourceResolver(new MyResourceResolver());
Run Code Online (Sandbox Code Playgroud)
我使用与JDK 1.7捆绑在一起的标准实现.我得到了例外:
src-resolve: Cannot resolve the …Run Code Online (Sandbox Code Playgroud) 如何使用xsom获取xsd的最大深度.
例如:xsd的每个复杂类型下的元素总数?
此外,如果复杂类型下复杂类型下的元素+属性的数量......使用dom\xsom\jaxb
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="root" type="root">
<xs:annotation>
<xs:documentation>
Comment describing your root element
</xs:documentation>
</xs:annotation>
</xs:element>
<xs:complexType name="root">
<xs:sequence>
<xs:element name="element_count" type="xs:string"></xs:element>
<xs:element name="employee" type="employee" maxOccurs="unbounded" minOccurs="0"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="employee">
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
<xs:element name="ID" type="xs:string"></xs:element>
<xs:element name="Addresses" type="addresses" maxOccurs="1" minOccurs="0"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="addresses">
<xs:sequence>
<xs:element name="address" type="address" maxOccurs="unbounded" minOccurs="0"></xs:element>
</xs:sequence>
</xs:complexType>
<xs:complexType name="address">
<xs:sequence>
<xs:element name="line1" type="xs:string"></xs:element>
<xs:element name="line2" type="xs:string"></xs:element>
<xs:element name="city" type="xs:string"></xs:element>
<xs:element name="type" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>
Run Code Online (Sandbox Code Playgroud)