【问题标题】:How to allow an XML element to appear anywhere via XSD?如何允许 XML 元素通过 XSD 出现在任何地方?
【发布时间】:2017-04-13 12:07:10
【问题描述】:

我有以下 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 中的everywhere,但同时允许包含 any 元素,这是允许的元素放进去。

我该如何定义?目前,我的 XML 架构中有大约 90 种类型/元素,手动编辑每个类型/元素以允许 if 元素允许正确的子元素是非常麻烦的。

是否可以创建一个允许if 元素的架构,如上所述?

【问题讨论】:

    标签: xml xsd


    【解决方案1】:

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

    你不能在 XSD 中做到这一点。如果不修改那些特定的指令,或者没有事先为这种可能性做准备,你就不能以这种方式全局地对抗你所有的特定约束. (例如,如果您定义了一个element substitution group,它可能会出现在您的文档中的多个位置,那么您可以轻松地将新成员添加到组中。)

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

    一个建议可能是在 XML 的 with-if 和 without-if 形式之间编写一个简单的 XSLT 转换,并分别验证这些文档。

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

    【讨论】:

    • 使用属性 () 听起来很有希望。我会评估这是否满足我的需求。
    【解决方案2】:

    虽然这个答案来晚了,但我想我会为完整性和未来的读者做出贡献。

    如果验证规则很重要,我会推荐 kjhughes 的 answer 中的 if 属性。 OTOH,OP 没有指定是否必须验证 &lt;if&gt;,只是寻求一种通用的、非侵入性的、基于 XML 模式的解决方案。

    如果不需要验证 &lt;if&gt;处理指令 (PI) 可能会提供 OP 所需的内容:根本无需编辑架构,它们可用于定义替代内容,具体取决于目标环境(DEV/PROD)。

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

    <root>
      <someNode>
        <?environment DEV?>
        <someChild attr="val" />
    
        <?environment PROD?>
        <someChild attr="otherVal" />
      </someNode>
    
      <otherNode>
        <otherChild>
          <?environment DEV?>
          <otherSubChild />
        </otherChild>
      </otherNode>
    </root>
    

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

    【讨论】:

    • 验证 XML (definition) 不是模式的唯一目的吗?因此,OP 确实需要验证他的 XML。
    • @Thomas OP 肯定需要验证他的 XML(否则为什么要使用模式),但不一定有替代环境的事实(&lt;if&gt;)。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-26
      • 1970-01-01
      • 2023-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多