问题:是否有一种方法(使用类似 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
配置中是否有一种方法可以确保 tableElement
的 name
属性包含在用户在运行时在 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/