代码之家  ›  专栏  ›  技术社区  ›  Varun

有没有办法从现有的xml文件生成dtd和xsd?[已关闭]

  •  0
  • Varun  · 技术社区  · 7 年前

    2 回复  |  直到 7 年前
        1
  •  4
  •   C. M. Sperberg-McQueen    7 年前

    可以轻松生成DTD,您可以根据该DTD验证文档:

    <!ELEMENT e (#PCDATA | e)* >
    

    对于XSD,模式文档仅包含

    <xsd:element name="e"/>
    

    for each $gi in distinct-values($input/descendant-or-self::*/name())
    return '<!ELEMENT ' || $gi || ' ANY >&#xA;'
    

    对于XSD,将return语句更改为

    return '<xsd:element name="{$gi}"/>'
    

    如果这些都不令人满意,那么您可能忘记了说明文档语法应该遵守哪些其他约束。

    我们可以生成一个语法,捕捉输入中的父/子关系(即,当且仅当某个e元素作为F元素的子元素出现在输入中时,它允许任何元素e都是元素F的子元素),代码如下

    for each $gi in distinct-values($input/descendant-or-self::*/name())
    let $occurrences := $input/descendant-or-self::*[name() = $gi]
        $children := distinct-values($occurrences/*/name(),
        $mixed := some $t in $occurrences/child::text()
                  satisfies normalize-space($t),
        $contentmodel0 := string-join(
                          (if ($mixed) then '#PCDATA' else (), $children),
                          ' | '
                          )
    return '<!ELEMENT ' || $gi || ' ' 
           || '(' 
           || $contentmodel0
           || ')* >&#xA;'
    

    我将把等效的XSD公式留给读者作为练习。

    如果语法捕捉输入中的父/子关系还不够,但您还希望允许语法中的任何元素“匹配”(在某种意义上)输入中的示例的子序列,那么您遇到了一个有趣的问题(值得一篇硕士论文或不久前的一篇论文):对于输入中元素E的每个实例,你有一些有限数量的子序列:你的任务是定义一种包含这些序列的规则语言,并清楚地捕捉输入的隐含模式。很明显,这在很大程度上取决于你对“喜欢”和“清楚”的定义。

    如果您的要求是在语法中允许一系列子元素,当且仅当它在输入中实例化时,那么元素E的内容模型的公式是简单的,对于DTD和XSD来说,仅通过决定论规则(在XSD中称为“唯一粒子属性规则”,这只是说“决定论规则”的一种稍微不那么清晰、更具说服力的方式)是复杂的。对于任何给定的序列集,可能有多个可能的公式作为内容模型;选择最简单的公式将需要对内容模型的复杂性进行一些度量,并以某种方式找到最简单的可用公式。

    ul 最终的内容模型如下 (li, li, li, li, (li, li, li, li, li)?) 因为输入有两个列表,一个有四个项目,一个有九个项目。如果您希望程序为列表生成“更简单”或“更好”的内容模型,例如 (li+) (li*)

    总之:有无限多的文档语法将接受有效的XML输入。如果它们对您的目的并不都同样有用,那么您需要更严格地约束您的问题,以便得到有用的答案。

    更多信息请访问 this earlier Stack Overflow question ,如果您在发布问题之前搜索了该网站的答案,您应该会找到它。

        2
  •  2
  •   Majd Yafi    7 年前

    您可以将此在线工具用于小xml文件 http://xmlgrid.net/xml2xsd.html