【问题标题】:DTD for optional elements wihout duplicates没有重复的可选元素的 DTD
【发布时间】:2020-06-10 15:19:06
【问题描述】:

我期待DTD,其中xml文件中的每个元素都是可选的,但如果有多个,则必须按正确的顺序排列。并且必须至少有一项没有重复项。

在这种情况下,至少没有一个

<!DOCTYPE mnop [
<!ELEMENT abcd      (#PCDATA)>
<!ELEMENT efgh      (#PCDATA)>
<!ELEMENT ijkl      (#PCDATA)>
<!ELEMENT mnop      (abcd?, efgh?, ijkl?)>
]> 
<mnop> 
</mnop> 

在这种情况下可能有重复

<!DOCTYPE mnop [
<!ELEMENT abcd      (#PCDATA)>
<!ELEMENT efgh      (#PCDATA)>
<!ELEMENT ijkl      (#PCDATA)>
<!ELEMENT mnop      (abcd?, efgh?, ijkl?)+>
]> 
<mnop> 
    <abcd>AAAAAAA</abcd>
    <abcd>AAAAAAA</abcd>
</mnop> 

在这种情况下(我不知道为什么!)但是在 xml 中的顺序可能不正确(DTD 有效)

<!DOCTYPE mnop [
<!ELEMENT abcd      (#PCDATA)>
<!ELEMENT efgh      (#PCDATA)>
<!ELEMENT ijkl      (#PCDATA)>
<!ELEMENT mnop      ((abcd, efgh?, ijkl?) | (abcd?, efgh, ijkl?) | (abcd?, efgh?, ijkl))>
]> 
<mnop> 
    <efgh>EEEEE</efgh>
    <abcd>AAAAAAA</abcd>
    <ijkl>AAAAAAA</ijkl>
</mnop> 

例如正确的文件:

<mnop> 
    <abcd>AAAAAAA</abcd>
</mnop> 
<mnop> 
    <efgh>EEEEE</efgh>
    <ijkl>AAAAAAA</ijkl>
</mnop> 
<mnop> 
    <ijkl>AAAAAAA</ijkl>
</mnop> 

每个案例都按正确的顺序排列,没有重复。 在我的示例中,我说的是 3 个元素,但在我的例子中,我有 12 个元素。

【问题讨论】:

    标签: xml dtd


    【解决方案1】:

    很简单

    <!ELEMENT mnop      ((a, ((b, c?) | c)?) | (b, c?) | c)? >
                        -----------------------------------^ all optional
                         (----------------)    (-----)  (-) starting with a/b/c
                         recursive
    

    请注意,这需要一个生成器工具,用 java 或 python 等编写。 当然是 12 个元素。

    从外到内的可选性:(x, (...)?)

    替代品会更好。


    Java:

    void p(StringBuilder sb, List<String> tags) {
        if (tags.isEmpty()) {
            throw new IllegalStateException();
        }
        int n = tags.size();
        if (n == 1) {
            sb.append(tags.get(0));
            return;
        }
        sb.append('(');
        for (int starti = 0; starti < n; ++starti) {
            if (starti != 0) {
                sb.append(" | ");
            }
            if (n - starti > 1) {
                sb.append('(');
            }
            sb.append(tags.get(starti));
            if (n - starti > 1) {
                sb.append(", ");
                p(sb, tags.subList(starti + 1, n));
                sb.append("?)");
            }
        }
        sb.append(')');
    }
    
        StringBuilder all = new StringBuilder();
        p(all, Arrays.asList("a", "b", "c"));
        all.append('?');
        System.out.println(all);
    

    ((a, ((b, c?) | c)?) | (b, c?) | c)?

    (我没有测试过。)

    【讨论】:

      猜你喜欢
      • 2012-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-26
      • 1970-01-01
      • 1970-01-01
      • 2016-05-02
      • 1970-01-01
      相关资源
      最近更新 更多