XML 表示键值对的架构

XML Schema for representing key-value pairs

在我的 Java 程序中,我想将 XML 解析为 Map。为此,我想创建一个模式来确保键名是唯一的并且没有嵌套。例如,这将是有效的:

<?xml version="1.0" encoding="UTF-8"?>
<Data>
    <WaterLevel>4.1</WaterLevel>
    <Voltage>5</Voltage>
    <Pressure>30</Pressure>
</Data>

也就是说,嵌套深度不应超过2层(即只允许在根以下一层)。此外,元素名称必须是唯一的。例如,不应有 2 "WaterLevel" 个元素。我需要执行什么 XSD?

I would be interested to know how it can be done in XSD 1.1 though, just to understand the challenge.

确保任意元素名称是唯一的既是动态约束又是文档范围的约束。它是动态的,因为不能预先定义元素名称(在 XSD 文档中通常是这样做的)。

在我看来,您的问题不适合 XSD,但可以用 XSD 1.1 解决。在那里,您可以使用测试 XPath 表达式的断言。这是一个例子:

XML 架构 1.1

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="Data">
        <xs:complexType>
            <xs:sequence>
                <!--Allowing arbitrary element names-->
                <xs:any maxOccurs="unbounded" processContents="lax"/>
            </xs:sequence>
            <!--Element names must be unique-->
            <xs:assert test="every $child in * satisfies not($child/preceding::*[name() = name($child)])"></xs:assert>
        </xs:complexType>
    </xs:element>

</xs:schema>

上面的架构会认为您的文档有效,但会拒绝像

这样的文档
<?xml version="1.0" encoding="UTF-8"?>
<Data>
    <WaterLevel>4.1</WaterLevel>
    <Voltage>5</Voltage>
    <Pressure>30</Pressure>
    <Voltage/>
</Data>

其中 Voltage 元素出现了两次。但我必须强调,这可能不是一个好主意,而且您对实例文档的 XML 内容没有太多控制权 - 而控制权是 XML 验证的重点。

有关任意元素名称的可行性的更多解释,请参阅 this related answer。 Michael Kay 回答的要点是:元素名称任意的 XML 设计设计得很糟糕。