首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从xsd中提取路径

问从xsd中提取路径
EN

Stack Overflow用户
提问于 2013-03-06 02:26:58
回答 3查看 2.1K关注 0票数 1

假设我有以下XML文档:

代码语言:javascript
复制
<foo>
  <bar/>
  <bang bash="hello">
    <foobar>123</foobar>
  </bang>
</foo>

我想提取这个文档中不同叶子的所有路径的列表,例如:

代码语言:javascript
复制
foo
foo.bar
foo.bang
foo.bang.@bash
foo.bang.foobar

这个过程有专门的术语吗?

更进一步:假设我有一个用于非常复杂的XML schema的.xsd。有没有一种简单的方法可以从.xsd中提取所有这样的路径?

(通过简单的方式,理想情况下,我的意思是某个地方是否存在这样的库?)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-03-06 11:34:18

A similar question是在SO上发布的。除了我在相关帖子中描述的方案之外,我仍然不知道针对您的场景有任何开箱即用的解决方案(API或其他)。

我是第一个认识到即使是我在本文中描述的the solution也可能缺少对某些XSD特性的覆盖,或者可能不符合人们对应该如何生成某些XPaths的特定期望。它可以支持您更新的请求中的内容(包括额外的“元数据”,例如XPath匹配的节点类型),因为可以使用自定义公式添加计算列以匹配您的模式。

虽然C.M.Sperberg-McQueen描述的算法确实让您对它可能涉及的一些事情有了一个概念,但它也被一个关于简单思想方法的温和“免责声明”所框定,这实际上意味着XSD规范涵盖的许多场景被省略了。

除非您的XSD真的很简单,否则就把它当做一个预告片吧!一些“糟糕”的例子:通过复杂类型(不仅仅是元素引用)递归的XML结构很棘手,当类型层次结构在XSD的设计中非常繁重和普遍时更是如此;使用抽象类型的元素(想想xsi:实例XML中的类型属性),使用block属性,form属性,使用变色龙XSD(现在步骤1本身就很有趣,更不用说如果在模式级别对元素/属性表单使用不同的默认值)。

如果您发现这些额外的“细节”适用于您的XSD,那么我建议您忘记XQuery或XSLT,使用专门的Schema Object Model API (XSOM on Java,.NET也有一个非常好的)来遍历您的XSD -在这里,我只是重复了@pgfearo所说的话(据我所知,SAXON XSD支持只在付费版本中可用;而Apache和JAXB为您免费提供了XSOM )。那么你就不需要担心很多事情了,而且很有可能你能在合理的时间内完成它。

票数 1
EN

Stack Overflow用户

发布于 2013-03-06 03:25:10

在SGML社区中,您要查找的值(当它们涉及元素时)被称为“完全限定的通用标识符”或FQGIs;因为‘’是XML中的合法名称字符,在SGML引用的具体语法中,FQGIs通常用斜杠写在您要写点的地方。(我将在这里扩展术语FQGI,并使用它表示您感兴趣的字符串,包括表示属性的字符串,而不是表示元素的字符串。)

我不知道用于查找所有可能出现在对特定模式有效的文档中的所有FQGI集合的过程的任何术语。请记住,在许多XML词汇表中,这是一个无限集合;如果希望进程终止,则需要确定所有可能的FQGIs的有限子集。

但是你需要遵循的过程是相对简单的。一个简单的版本运行如下:

XSLT如果您感兴趣的模式是跨多个模式文档定义的,那么可以将它们整合到一个文档(一个具有多个xs:schema子级的包装器)中,或者放入一个模式文档的集合中,该集合可以使用XSLT或XQuery.

  1. Identify处理您希望从其开始的一组元素声明和属性声明。(在您的示例中,此集合可能包含foo的顶级元素声明。)对于这个集合中的每一项,写下它的名称和类型。将这组字符串/类型对称为S。
  2. 将集合S复制到集合S‘中。
  3. 以以下方式创建集合S'’:以S'‘空开头,然后对于S’中的每个项目,设N为FQGI,T为项目中命名的类型,并且:

(a)如果N表示属性,则不执行任何操作。

(b)如果N表示一个元素,则标识可能出现在该元素上的属性集。对于每个这样的属性,标识其类型T2,并通过连接N、斜杠、at符号和属性的扩展名称来创建字符串N2。将(N2,T2)对添加到S'‘。

(c)如果N表示元素,则找到(i)出现在T的内容模型中,(ii)匹配T的内容模型中的通配符,或(iii)可替换在(i)或(ii)中命名的元素的元素集。对于每个这样的可能的子对象,标识子对象的类型T3,并通过连接N、"/“和可能的子对象的扩展名称来生成字符串N3。将(N3,T3)对添加到S'‘.

  • 如果S’‘为空,则完成,并且您的答案是集合S和集合S’的并集。否则,让(新的)S是S和S‘的并集,让(新的)S’等于S',并转到步骤4。

稍微反思一下就会发现,可以匹配通配符的名称集是无限的,因此不能完整处理步骤4(c)中的列表(ii)。您可以通过各种方式选择列表的有限子集;选择哪个子集取决于您希望FQGI列表的用途。

再多一点思考就会告诉您,如果词汇表中的任何元素都可以作为其自己的后代出现(如HTML的div或li元素),那么所描述的过程将永远不会结束。同样,有多种方法可以修剪在4(c)中生成的配对集以保证终止。

我不知道有什么库可以做到这一点,也许是因为对于有趣的XML词汇表来说,可能的FQGI集很少是有限的。使用XQuery引擎或在XSLT样式表中完成这项工作非常容易。

票数 2
EN

Stack Overflow用户

发布于 2021-01-14 20:39:05

为此,我创建了一个Java工具XsdPathTypeGenerator。它还提取元素和属性类型。

给定XSD:

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://smitek.co.uk/example/1">
    <xsd:element name="employee">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="name" type="xsd:string"/>
                <xsd:element name="department">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="name" type="xsd:string"/>
                        </xsd:sequence>
                        <xsd:attribute name="code" type="xsd:integer"/>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
            <xsd:attribute name="active" type="xsd:boolean"/>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

它将创建一个Map

代码语言:javascript
复制
employee@active=xsd:boolean
employee/name=xsd:string
employee/department@code=xsd:decimal
employee/department/name=xsd:string

它有一定的局限性,这意味着你将它作为一个工具来运行,而不是将它作为一个库来使用,这会让我变得懒惰,但它至少解决了我的问题:)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15231305

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档