有没有办法从现有的 xml 文件生成 dtd 和 xsd?
Is there a way to generate a dtd and xsd from an existing xml file?
我写了一篇xml。我想为它生成一个 dtd 和 xsd。有没有我可以使用相同的工具而不是键入所有内容这样我就可以避免错误?期待一些 inputs/leads.
您可以将此在线工具用于小 xml 文件
http://xmlgrid.net/xml2xsd.html
可以轻松生成您可以用来验证文档的 DTD:
<!ELEMENT e (#PCDATA | e)* >
或者对于 XSD,一个仅包含
的架构文档
<xsd:element name="e"/>
如果这不令人满意,也许您忘记说您希望 DTD 接受您的 XML 文档是有效的。在这种情况下,我会在 XSLT 或 XQuery
中实现类似于以下 pseudo-code 的内容
for each $gi in distinct-values($input/descendant-or-self::*/name())
return '<!ELEMENT ' || $gi || ' ANY >
'
对于XSD,将return语句更改为
return '<xsd:element name="{$gi}"/>'
如果这些都不令人满意,也许你忘了说文档语法还应该遵守哪些其他约束。
我们可以生成一个语法来捕获输入中的 parent/child 关系(即它允许任何元素 E 是元素 F 的 child 当且仅当某些 E 元素出现在输入为 F 元素的 child),代码如
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
|| ')* >
'
我将保留等效的 XSD 公式作为 reader 的练习。
如果语法捕获输入中的 parent/child 关系还不够,但您还希望语法中任何元素允许的 children 序列为 'match' (在某种意义上)输入中的示例,然后你遇到了一个有趣的问题(值得一篇硕士论文或不久前的一篇论文):对于输入中元素 E 的每个实例,你有一些有限数量的序列 children:你的任务是定义一种包含这些序列并清楚地捕获输入的隐式模式的常规语言。很明显,很大程度上取决于您对 'like' 和 'clearly' 的定义。
如果您的要求是 children 的序列当且仅当它在输入中被实例化时才允许在语法中使用,那么元素 E 的内容模型的公式很简单,对于 DTD 则很复杂和 XSD 仅由确定性规则(在 XSD 中称为 'unique particle attribution rule',这只是 'determinism rule' 的一种不太清晰但更具说服力的说法)。对于任何给定的序列集,可能有不止一种可能的表述作为内容模型;选择最简单的将需要对内容模型的复杂性进行某种度量,并需要某种方法来找到最简单的可用公式。
如果您使用示例 HTML 文档进行此实验,您可能会发现 ul
最终会得到类似 (li, li, li, li, (li, li, li, li, li)?)
的内容模型,因为输入有两个列表,一个是四项和一项九项。如果您希望您的程序为列表生成 'simpler' 或 'better' 内容模型,例如 (li+)
或 (li*)
,那么您希望您的语法不仅允许有限数量的sequence children 在输入中找到,而且还有其他 sequences "like" 它们。也就是说,您必须找到一种合适的方法来从输入中进行归纳。有无数种方法可以做到这一点(即使 class 法律概括受到严格限制,就像现在任何人都知道该怎么做一样,仍然有很多方法),并选择一种感觉'right' 对于大多数软件来说,对人类来说可能是困难的。
总而言之:有无数的文档语法会接受您的 XML 输入为有效。如果它们对您的目的并非都同样有用,那么您需要更严格地限制您的问题,以便它有一个有用的答案。
更多信息可在 this earlier Stack Overflow question 中找到,如果您在发布问题之前已在网站上搜索过答案,您应该已经找到了。
我写了一篇xml。我想为它生成一个 dtd 和 xsd。有没有我可以使用相同的工具而不是键入所有内容这样我就可以避免错误?期待一些 inputs/leads.
您可以将此在线工具用于小 xml 文件 http://xmlgrid.net/xml2xsd.html
可以轻松生成您可以用来验证文档的 DTD:
<!ELEMENT e (#PCDATA | e)* >
或者对于 XSD,一个仅包含
的架构文档<xsd:element name="e"/>
如果这不令人满意,也许您忘记说您希望 DTD 接受您的 XML 文档是有效的。在这种情况下,我会在 XSLT 或 XQuery
中实现类似于以下 pseudo-code 的内容for each $gi in distinct-values($input/descendant-or-self::*/name())
return '<!ELEMENT ' || $gi || ' ANY >
'
对于XSD,将return语句更改为
return '<xsd:element name="{$gi}"/>'
如果这些都不令人满意,也许你忘了说文档语法还应该遵守哪些其他约束。
我们可以生成一个语法来捕获输入中的 parent/child 关系(即它允许任何元素 E 是元素 F 的 child 当且仅当某些 E 元素出现在输入为 F 元素的 child),代码如
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
|| ')* >
'
我将保留等效的 XSD 公式作为 reader 的练习。
如果语法捕获输入中的 parent/child 关系还不够,但您还希望语法中任何元素允许的 children 序列为 'match' (在某种意义上)输入中的示例,然后你遇到了一个有趣的问题(值得一篇硕士论文或不久前的一篇论文):对于输入中元素 E 的每个实例,你有一些有限数量的序列 children:你的任务是定义一种包含这些序列并清楚地捕获输入的隐式模式的常规语言。很明显,很大程度上取决于您对 'like' 和 'clearly' 的定义。
如果您的要求是 children 的序列当且仅当它在输入中被实例化时才允许在语法中使用,那么元素 E 的内容模型的公式很简单,对于 DTD 则很复杂和 XSD 仅由确定性规则(在 XSD 中称为 'unique particle attribution rule',这只是 'determinism rule' 的一种不太清晰但更具说服力的说法)。对于任何给定的序列集,可能有不止一种可能的表述作为内容模型;选择最简单的将需要对内容模型的复杂性进行某种度量,并需要某种方法来找到最简单的可用公式。
如果您使用示例 HTML 文档进行此实验,您可能会发现 ul
最终会得到类似 (li, li, li, li, (li, li, li, li, li)?)
的内容模型,因为输入有两个列表,一个是四项和一项九项。如果您希望您的程序为列表生成 'simpler' 或 'better' 内容模型,例如 (li+)
或 (li*)
,那么您希望您的语法不仅允许有限数量的sequence children 在输入中找到,而且还有其他 sequences "like" 它们。也就是说,您必须找到一种合适的方法来从输入中进行归纳。有无数种方法可以做到这一点(即使 class 法律概括受到严格限制,就像现在任何人都知道该怎么做一样,仍然有很多方法),并选择一种感觉'right' 对于大多数软件来说,对人类来说可能是困难的。
总而言之:有无数的文档语法会接受您的 XML 输入为有效。如果它们对您的目的并非都同样有用,那么您需要更严格地限制您的问题,以便它有一个有用的答案。
更多信息可在 this earlier Stack Overflow question 中找到,如果您在发布问题之前已在网站上搜索过答案,您应该已经找到了。