java - XSD 配置以在运行时引用 XML 文件中配置的属性

标签 java xml xsd

问题:是否有一种方法(使用类似 tns: 的方法)为 XML 文件设置 .xsd 配置以引用运行时在 XML 文件中配置的属性列表?

这是我的情况:

我有一个 .xsd 架构文件 Labels.xsd,用于 xml 文件 Labels.xml

Labels.xsd 包含以下内容:

<complexType name="LabelList">
    <sequence>
        <element name="label" type="tns:MyLabel" maxOccurs="unbounded"
            minOccurs="1"/>
    </sequence>
</complexType>

<complexType name="MyLabel">
    <attribute name="labelName" type="token" use="required"/>
    <!-- There are other attributes and sequences in MyLabel -->
</complexType>

用户可以添加到 Labels.xml 文件并添加自己的自定义标签,并在我的 java 应用程序运行时更改名称。更改会在运行时生效。

我有另一个文件 MyMainTable.xml,它使用 Tables.xsd 中的架构。此文件使用上面 Labels.xml 文件中的标签创建一个表。该架构与 Labels.xml 文件的架构位于不同的架构文件中。

Tables.xml 文件包含以下内容:

<complexType name="MyMainTable">
    <sequence>
        <element name="table" maxOccurs="unbounded">
            <complexType>
                <sequence>
                    <element name="tableElement" maxOccurs="unbounded">
                        <complexType>
                            <attribute name="name" type="string" use="required">
                                <annotation>
                                    <documentation>
                                    This should be one of the types of 
                                    MyLabel.label.labelName that are configured in the 
                                    LabelList sequence
                                    Users can change the names of and add to the 
                                    types in MyLabel.labelName xml file.
                                    </documentation>
                                </annotation>
                            </attribute>
                        </complexType>
                    </element>
                </sequence>
                <!-- There are other attributes in this type, but they are not relevant -->
             </complexType>
         </element>
     </sequence>
</complexType>

Labels.xml 示例:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Labels xmlns="<my schema locaiton>">

<FavoriteLabels>
   <label labelName="LabelA">
     <!-- other attributes such as color -->
   </label>
   <label labelName="LabelB">
     <!-- other attributes such as color -->
   </label>
   <label labelName="LabelC">
     <!-- other attributes such as color -->
   </label>
</FavoriteLabels>

<OtherLabels>
   <label labelName="OtherA">
     <!-- other attributes such as color -->
   </label>
   <label labelName="OtherB">
     <!-- other attributes such as color -->
   </label>
   <label labelName="OtherC">
     <!-- other attributes such as color -->
   </label>
</OtherLabels>
</Labels>

tableElement中的名称可以在FavoriteLabels列表或OtherLabels列表中

目前,我在构建表时在 Java 代码中进行检查,但我希望在解析 XML 文件时进行检查。类似于对 .xsd 文件中配置的 Enum 进行检查的方式。

.xsd 配置中是否有一种方法可以确保 tableElementname 属性包含在用户在运行时在 Labels.xml 文件中配置的标签列表中?

最佳答案

我在下面修改了您的示例。它可能会捕获您正在尝试解决的问题,或者至少向您展示可能的策略。

这是一个包含标签和表格的 XML 文件。

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://my-namespace my-schema.xsd"
      xmlns="http://my-namespace">
    <labels>
        <label label="LabelA"/>
        <label label="LabelB"/>
        <label label="LabelC"/>
    </labels>
    <tables>
        <table name="LabelB"/> 
        <table name="LabelB"/>
        <table name="LabelA"/> 
        <table name="LabelC"/>
    </tables>
</root>

您可能可以使用单独的文件(我无法仅使用 XML 架构来做到这一点,因为 key/keyref 关联使用 XPath;但这可能是可能的,或者您可以在处理文件之前将它们合并到内存中)。

在架构中,我定义了一个键/键引用对,将标签与表相关联。这些关联是在定义它们的元素的上下文中使用 XPath 进行的。我使用 ID 和 IDREF 作为 token 类型,因为它们更严格并且保证整个文档的唯一性。

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified"
    xmlns:tns="http://my-namespace" targetNamespace="http://my-namespace">

    <xs:complexType name="LabelList">
        <xs:sequence>
            <xs:element name="label" maxOccurs="unbounded" minOccurs="1">
                <xs:complexType>
                    <xs:attribute name="label" type="xs:ID" use="required"/>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:complexType name="TableList">
        <xs:sequence>
            <xs:element name="table" maxOccurs="unbounded">
                <xs:complexType>
                    <xs:attribute name="name" type="xs:IDREF" use="required"/>                   
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:complexType>

    <xs:element name="root">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="labels" type="tns:LabelList"/>
                <xs:element name="tables" type="tns:TableList"/>
            </xs:sequence>
        </xs:complexType>

        <!-- These are the keys and references; they are in the current element's context -->
        <xs:key name="LabelsKey">
            <xs:selector xpath="labels/label"/>
            <xs:field xpath="@label"/>
        </xs:key>
        <xs:keyref name="TablesRef" refer="tns:LabelsKey">
            <xs:selector xpath="tables/table"/>
            <xs:field xpath="@name"/>
        </xs:keyref>

    </xs:element>
</xs:schema>

现在如果添加列表中未定义的标签的表格,例如:

<table name="LabelZ"/>

您将收到验证错误。

关于java - XSD 配置以在运行时引用 XML 文件中配置的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21686430/

相关文章:

xsd - 使用 jaxb 从我的类路径中的 xsd 生成源代码

java - getters 和 setters 需要同步

java - 有状态 session bean 的消息驱动 bean 没有响应

.net - Visual Studio 2010 中 xsd.exe 的替代品

php - 我可以 POST 和 GET 到同一个 PHP 页面吗

xml - 注销上下文节点范围内的命名空间

java - 需要帮助安装和运行 Spring Petcare 示例应用程序

java - 为什么java多线程不能加速图形程序

java - 基本 LWJGL 程序黑屏

xml - 如何去除xslt中元素值的额外空间