如何创建允许一个或多个<a> followed by an equal number of <b>?</b></a>的XML架构

时间:2013-03-06 12:22:29

标签: xml xsd context-free-grammar xsd-1.0

我希望我的XML实例文档包含一个或多个<a/>元素,后跟相同数量的<b/>元素。以下是一些有效的实例:

<a/><b/>, <a/><a/><b/><b/>, <a/><a/><a/><b/><b/><b/>

我想使用XML Schema 1.0来实现它。

我试过这种方法:

<xs:group name="context-free-language">
    <xs:sequence>
        <xs:element name="a" fixed="a" />
        <xs:group ref="context-free-language" minOccurs="0" />
        <xs:element name="b" fixed="b" />
    </xs:sequence>
</xs:group>

不幸的是,不允许使用循环组引用。

有关如何实施此建议的任何建议?

4 个答案:

答案 0 :(得分:2)

您的要求是识别无上下文的语言。您不能使用模式语言中的内容模型来执行此操作,该模式语言要求内容模型为正则表达式,从而定义常规的非上下文语言。目前广泛使用的模式语言不允许内容模型定义无上下文语言。

您的选择是(1)将您的设计更改为使用您可以使用的技术而不是反对它,(2)使用临时流程(如InfantPro'Aravind建议的XSLT样式表),或( 3)在Schematron或XSD 1.1中使用断言来强制执行约束。

答案 1 :(得分:1)

XSD 1.0无法做到这一点。我认为1.1也不可能。

还有像Schematron这样的替代方法。或者可以使用XSLT转换并输出结果。可以验证哪个inturn以查看XML是否有效。

我将简要介绍第二种方法:

示例输入XML:

<?xml version="1.0" encoding="utf-8"?>
<root>
  <a/>
  <a/>
  <b/>
  <b/>
</root>

示例XSLT:

<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:template match="/root">
    <validation>
      <xsl:choose>
        <!--Output 'true' if count is equal .. and 'false' otherwise-->
        <xsl:when test="count(a)=count(b)">
          <xsl:text>true</xsl:text>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text>false</xsl:text>
        </xsl:otherwise>
      </xsl:choose>
    </validation>
  </xsl:template>
</xsl:stylesheet> 

因为count(a)等于count(b),所以输出:

<?xml version="1.0" encoding="utf-8"?>
<validation>true</validation>

并且将对以下内容进行验证:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="validation" type="xs:boolean" fixed="true"/>
</xs:schema>

在这种情况下会传递,因为<validation>节点的值为true

注意:XSLT只是创建一个我用于扩展验证的转换副本,它不会修改原始输入。

答案 2 :(得分:1)

InfantPro'Aravind'陈述错误:

This is not possible with XSD 1.0. I think not possible with 1.1 as well.

事实上,很有可能使用XSD 1.1断言。只需定义一个内容模型,允许任意数量的As后跟任意数量的B,然后添加断言

<xs:assert test="count(A) = count(B)"/>

答案 3 :(得分:-1)

XML Schema 1.0仅为无上下文语法提供部分支持。遗憾的是,它不支持需要相同数量的a和b的语法。另一方面,它确实支持一些无上下文的语法。我写了一篇文章解释了这一点:http://www.xfront.com/XML-Schema-1-0-and-Relax-NG-Partially-Support-Context-Free-Grammars.pdf

相关问题