如何允许XML元素通过XSD显示在任何地方?

如何允许XML元素通过XSD显示在任何地方?,xml,xsd,Xml,Xsd,我有以下XML: <root> <someNode> <someChild attr="val" /> </someNode> <otherNode> <otherChild> <otherSubChild /> </otherChild> </otherNode> </root> 为此,一个有效的XML模式将非常容易

我有以下XML:

<root>
  <someNode>
    <someChild attr="val" />
  </someNode>

  <otherNode>
    <otherChild>
      <otherSubChild />
    </otherChild>
  </otherNode>
</root>

为此,一个有效的XML模式将非常容易。现在的问题是,我的程序必须支持在解析文件时计算的特殊元素,并导致元素的条件替换

例如:

    <root>
      <someNode>
        <if environment="DEV">
          <someChild attr="val" />
        </if>
        <if environment="PROD">
          <someChild attr="otherVal" />
        </if>
      </someNode>

      <otherNode>
        <otherChild>
          <if environment="DEV">
            <otherSubChild />
          </if>
        </otherChild>
      </otherNode>
    </root>

我想你明白了。问题是,允许
if
元素在XML中的任何地方出现,但同时允许包含它所放入的元素所允许的任何元素

我如何以一种好的方式定义它?目前,我的XML模式中有大约90个类型/元素,手动编辑每个类型/元素以允许使用允许正确子元素的
if
元素将非常麻烦


是否可以创建一个模式来允许我上面描述的
if
元素?

因此,您已经指定了一个内容模型的层次结构,具体说明了哪些元素可以出现在哪些其他元素中,以什么数量,可能还以什么顺序出现。顺便说一下,现在您想添加一个
if
元素,它可以将任何现有元素包装到任何地方

在XSD中无法做到这一点。如果不修改这些特定说明,或者事先没有对这种可能性作出规定,就无法以这种方式全局对抗所有特定约束。(例如,如果您定义了一个可以在整个文档中显示多个位置的,则可以轻松地将新成员添加到组中。)

有一种方法可以说,任何元素都可以出现在内容模型中的某个给定位置(
xs:any
),但无法说给定元素可以出现在所有内容模型中的任何位置。在XSD1.1中,有一种新的机制允许在内容模型中使用,但这也允许前瞻性的规定,而不是追溯性的全局调整

一个建议是在XML的带if和不带if形式之间编写一个简单的XSLT转换,并分别验证这些文档


另一种方法是将条件表示为将出现在任何元素上的属性,而不是可以包装任何其他元素的元素。这仍然需要对XSD进行更新,但是,在保留现有内容模型的同时,更新将更容易进行。

也许您可以尝试为
元素及其属性定义一个基本的complexType,然后将
声明为该类型的扩展。

尽管这个答案来得晚,我想我会为完整性和未来的读者做出贡献

如果验证规则很重要,我建议使用kjhughes中的
if
属性。OTOH,OP没有指定是否必须验证
,只是寻找一种通用的、非侵入性的、基于XML模式的解决方案

如果不需要对
进行验证,处理指令(PI)可以提供OP所需的内容:完全不需要编辑模式,它们可以用于定义替代内容,具体取决于目标环境(DEV/PROD)

这正是PI设计的目的:它们不向xml数据添加内容(或者至少,我们不应该在其中添加内容);未经验证;它们只为数据的“处理器”增加了意义。解析XML的应用程序不需要理解它们(当然,这取决于您对它们所做的操作)



警告:根据架构,在
中包含2个
可能无效,在这种情况下,此文档需要在验证之前进行预处理,但这与
if
属性选项相同。

使用属性()听起来很有希望。我将评估这是否满足我的需要。验证XML不是模式的唯一目的吗?因此,OP确实需要验证他的XML。@Thomas OP肯定需要验证他的XML(否则为什么要麻烦使用模式),但不一定是因为存在替代环境(代码)。
<root>
  <someNode>
    <?environment DEV?>
    <someChild attr="val" />

    <?environment PROD?>
    <someChild attr="otherVal" />
  </someNode>

  <otherNode>
    <otherChild>
      <?environment DEV?>
      <otherSubChild />
    </otherChild>
  </otherNode>
</root>