XML模式仅将属性数据类型和所有节点值定义为字符串

时间:2018-10-23 07:48:40

标签: xml xsd

是否可以定义仅将属性数据类型和所有节点值定义为字符串的XML模式?

我正在处理一个具有以下结构的非常大的XML文件:

<A>
    <A_x1 label="xyz" id="1234">string data</A_x1>
    <A_x2 label="xzy" id="1235">string data</A_x2>
    <A_x...>string data</A_x...>
    ...
</A>
<B>
    <B_x1 label="yzx" id="1236">string data</B_x1>
    <B_x2 label="zyx" id="1237">string data</B_x2>
    <B_x...>string data</B_x...>
    ...
</B>
<C>
    ...
</C>
...

A或B或...的子节点数是可变的!

有时有一个节点A_x1,有时没有。

我可以肯定的是,每个离开节点都有两个属性,其中“标签”的数据类型为字符串,而“ id”的数据类型为int。

我认为可以这样定义:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:attribute name="label" type="xs:string"/>
  <xs:attribute name="id"    type="xs:short"/>
</xs:schema>

但是我如何定义一个架构,声明每个名为“ A_x ...”或“ B_x ...”或...的节点都保存着字符串类型的数据? 或每个请假节点都保存字符串类型的数据。

我找不到在XML模式中为节点名称使用正则表达式的方法,这有可能吗? 或该问题的解决方案是什么?如果有的话。

1 个答案:

答案 0 :(得分:1)

不幸的是,即使在XSD 1.1中,允许具有任何名称的元素的唯一方法是允许使用xs:any通配符,并且xs:any不允许您约束元素的类型匹配。

您可以使用XSD 1.1断言定义所有约束:

every $e in child::* satisfies if exists($e/@id) then $e/@id castable as xs:short

但是坦率地说,如果您这样做的话,那么XSD的价值就太少了,您不妨使用其他技术进行验证,例如XSLT或schematron。

另一种可能性(通常被忽略)是使用先进行转换(使用XSLT)然后进行验证(使用XSD)的管道进行验证。在这种情况下,转换部分会将所有元素名称A_x1转换为标准元素名称AA例如。

第三种可能性是为您的特定实例文档生成一个架构(再次使用XSLT),然后针对该架构进行验证。在这种情况下,您生成的架构可以将所有A_x1元素定义为某个抽象元素AA的替换组的成员,因此可以针对为AA定义的类型来验证这些元素。