如何正确验证XML模式的扩展?

时间:2017-11-24 20:38:22

标签: java xml xsd xsd-validation

我正在研究SCTE-224标准XML架构(http://www.scte.org/schemas/224/2015/SCTE224.xsd)的扩展。规范允许通过在Metadata元素中包含任何其他命名空间的元素来扩展标准:

<xs:element minOccurs="0" name="Metadata">
  <xs:complexType>
    <xs:sequence>
      <xs:any maxOccurs="unbounded" minOccurs="0" namespace="##other"/>
    </xs:sequence>
  </xs:complexType>
</xs:element>

我在自己的命名空间中定义了一些顶级元素,这些元素应该放在SCTE-224标准元素中。例如,bam:Program元素:

<Media id="/media/12345" description="A standard SCTE-224 Media element.">
  <Metadata>
    <bam:Program>
      ... Additional bam-namespaced elements
    </bam:Program>
  </Metadata>
</Media>

我的目标是能够拥有自己的XSD来定义扩展规范的模式,同时考虑标准和bam:元素中的元素。下面是对扩展元素的第一次尝试,但我无法弄清楚如何指定bam:Program元素必须出现在Media/Metadata内。

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://specs.bamgrid.com" targetNamespace="http://specs.bamgrid.com" xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:xlink="http://www.w3.org/1999/xlink"
           elementFormDefault="qualified"
           attributeFormDefault="unqualified">

  <xs:import namespace="http://www.w3.org/1999/xlink" schemaLocation="http://www.w3.org/1999/xlink.xsd"/>

  <xs:element name="Genres">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Genre">
          <xs:complexType>
            <xs:simpleContent>
              <xs:extension base="xs:string">
                <xs:attribute name="type" type="xs:string"/>
              </xs:extension>
            </xs:simpleContent>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:element name="Program">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="ProgramDetails" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="ProgramDetail" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element name="Title" type="xs:string" minOccurs="0"/>
                    <xs:element name="TitleBrief" type="xs:string" minOccurs="0"/>
                    <xs:element name="TitleSort" type="xs:string" minOccurs="0"/>
                    <xs:element name="Description" type="xs:string" minOccurs="0"/>
                    <xs:element name="DescriptionBrief" type="xs:string" minOccurs="0"/>
                  </xs:sequence>
                  <xs:attribute name="language" use="required">
                    <xs:simpleType>
                      <xs:restriction base="xs:string">
                        <xs:pattern value="[a-z][a-z]"/>
                      </xs:restriction>
                    </xs:simpleType>
                  </xs:attribute>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element name="ProgramType" type="xs:string" minOccurs="0"/>
        <xs:element name="Images" minOccurs="0">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Image" maxOccurs="unbounded">
                <xs:complexType>
                  <xs:attribute ref="xlink:href" use="required"/>
                  <xs:attribute name="height" type="xs:int" use="required"/>
                  <xs:attribute name="width" type="xs:int" use="required"/>
                  <xs:attribute name="type" type="xs:string"/>
                  <xs:attribute name="key" type="xs:string"/>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
        <xs:element ref="Genres" minOccurs="0"/>
      </xs:sequence>
      <xs:attribute name="contentSource" type="xs:string"/>
    </xs:complexType>
  </xs:element>
</xs:schema>

有人能指出我正确的方向来描述这个扩展架构吗?

1 个答案:

答案 0 :(得分:0)

我得到了##其他命名空间的解决方案,这是我们失败的原因。

首先,通过实现ValidationEventHandler接口来创建处理程序。

package com.packagename.handler;

import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author <tomer.madmon@imaginecommunications.com>
 *
 */
public class SCTE224Handler implements ValidationEventHandler {
    private static final Logger logger = LoggerFactory.getLogger(SCTE224Handler.class);
    @Override
    public boolean handleEvent(ValidationEvent event) {
        if(event.getMessage().contains("##other")){ // means ##other namespace like metadata in SCTE224 
            logger.warn(event.toString());
            return true;    
        }
        logger.error(event.toString());
        return false;
    }
}

然后,设置处理程序和架构,它将起作用。

Unmarshaller unmarshaller = jc.createUnmarshaller();
SCTE224Handler validatorHandler = new SCTE224Handler();
unmarshaller.setSchema(schema);
unmarshaller.setEventHandler(validatorHandler);