【问题标题】:How can I constrain XML content to other content in the XML (as a reference)?如何将 XML 内容限制为 XML 中的其他内容(作为参考)?
【发布时间】:2014-09-16 20:48:23
【问题描述】:

当且仅当method/key 中的id=*method/call 中的{*} 子字符串存在双射时,我想验证XML

  1. 有效,因为每个{*} 都与id=* 完全对应 反之亦然。

    <format>
      <call>
        /tags/{1}/top-askers/{2}
      </call>
      <key id="1">
        <name>tag</name>
        <discussion>a tag for the site</discussion>
      </key>
      <key id="2">
        <name>period</name>
      </key>
    </format>
    
  2. 无效,因为有一个id=* 没有对应的{*}

    <format>
      <call>
        /tags/{1}
      </call>
      <key id="1">
        <name>tag</name>
        <discussion>a tag for the site</discussion>
      </key>
      <key id="2">
        <name>period</name>
      </key>
    </format>
    
  3. 无效,因为有一个{*} 没有对应的id=*

    <format>
      <call>
        /tags/{1}/top-askers/{2}
      </call>
      <key id="1">
        <name>tag</name>
        <discussion>a tag for the site</discussion>
      </key>
    </format>
    
  4. 理想情况下,我也希望这也是可能的,这意味着{*} 的内容可以是[^}{] 中的任何一个。

    <format>
      <call>
        /tags/{tag}/top-askers/{2}
      </call>
      <key id="tag">
        <name>tag</name>
        <discussion>a tag for the site</discussion>
      </key>
      <key id="2">
        <name>period</name>
      </key>
    </format>
    

我查看了 XML 模式的 w3schools 参考,但它似乎没有列出任何此类功能。不过,这当然不是规范的完整参考。这在 XML 模式中是否可行?

更新

@JirkaŠ 提供了以下表达式,它解决了 (2) (和 (4)) 但不是 (3):

for $key in /format/key
  return matches($key/../call,
                 concat("\{", $key/@id, "\}"))

【问题讨论】:

    标签: xml validation xpath xsd


    【解决方案1】:

    IMO,在 XSD 1.0 中这是不可能的。当然有一些基本的约束(xs:unique, xs:key)。这些是使用 XPath 表达式定义的,但该表达式只是整个 XPath 语言的子集(请参阅http://docstore.mik.ua/orelly/xml/schema/ch09_02.htm 中的第 9.2.5 章)。 在这种情况下,最大的限制是不允许函数调用,您可能需要一些字符串操作函数,因为“调用”元素内容是一个字符串。

    如果您可以使用 XSD 1.1,那么还有一些其他功能可以表达更复杂的限制,特别是我有“xs:assert”的想法。我认为 xpath 函数可能会在 XSD 1.1 中调用。

    【讨论】:

    • 这完全可以使用 XPath 2.0 中的for 表达式;你想在我工作的时候试一试吗?它看起来像一个有趣的问题来解决(如果你这样滚动)。如果没有,我可以尝试在午餐时尝试一下(如果工作中没有更多紧迫的弹出......)。
    • 你的 xpath 表达式在哪里?在 XSD 中?能否提供相应的 xsd 定义?
    • 可能像for $key in /format/key return matches($key/../call, concat("\{", $key/@id, "\}")) 这样的东西可以工作?
    • 这至少是故事的一半——我很快就会在这里更新我原来的帖子。
    • 嗯,3 是一个真正的挑战(至少对我来说)。我为此尝试了for $call in /format/call, $id in tokenize(normalize-space($call), '\{|\}')[position() mod 2 = 0] return $call/../key/@id = $id 之类的东西。但这不是防弹解决方案,因为我不是正则表达式的专家(例如,如果有 } 而没有相应的 {,它会失败)。但这可能会给你一些启发。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-06
    • 1970-01-01
    • 2019-11-30
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多