我正在尝试为我的应用程序设计XML文档结构。
我想存储一个像下面这样的漏洞列表
<Holes>
<Hole id='1' dia='0.1' depth='2'/>
<Hole id='2' dia='0.2' depth='1.67'/>
<Hole id='3' dia='0.3' depth='0.44'/>
</Holes>
在我的文档的另一部分中,我想通过它的id引用一个洞。 e.g。
<Drill useHoleWithId='1'/>
当我的代码找到上面的&lt; Drill&gt; element我希望它在&lt; Hole&gt;中检索'dia'和'depth'属性的值id ='1'的元素。
当然我可以搜索&lt; Hole&gt; id等于'useHoleWithId'值的元素,然后获取属性的值,但我想也许有更好的方法来使用一些XML技巧来做到这一点。有吗?
PS - 虽然我对它们一无所知,但可能是XPath,XLink,XQuery或XPointer中的任何一个都可以提供帮助。
答案 0 :(得分:4)
XPath肯定是一种方法。用于查找ID为1的保留的Xpath查询类似于Holes/Hole[@id="1"]
答案 1 :(得分:3)
有一个标准的XPath函数可以通过“id”属性来引用元素。
来自XPath 1.0规范。:
id()
函数函数按唯一ID
选择元素(参见[5.2.1唯一ID])。当id
的参数的类型为node-set
时,结果是将id
应用于参数中每个节点的string-value
的结果{ {1}}。当node-set
的参数是任何其他类型时,参数将转换为id
,就好像通过调用string
一样; string function
被分为string
(whitespace-separated list of tokens
是与作品whitespace
匹配的任何字符序列);结果是S
包含与node-set
相同document
的元素,其context node
等于列表中的任何标记。
unique ID
选择具有唯一id("foo")
foo的元素
ID
选择了第五个孩子
具有唯一id("foo")/child::para[position()=5]
foo
在XSLT 中可以使用另一种更通用的方式来引用节点(不仅仅是元素)。 <xsl:key/>
指令和XSLT key()
功能专门用于此目的。
例如,假设一个文档包含XSLT形式的书目引用,并且有一个单独的XML文档bib.xml,其中包含一个带有以下形式的条目的书目数据库:
ID
然后样式表可以使用以下内容转换bibref元素:
<entry name="XSLT">...</entry>
请注意,XSLT中的键克服了<xsl:key name="bib" match="entry" use="@name"/>
<xsl:template match="bibref">
<xsl:variable name="name" select="."/>
<xsl:for-each select="document('bib.xml')">
<xsl:apply-templates select="key('bib',$name)"/>
</xsl:for-each>
</xsl:template>
函数的以下限制:
必须将ID属性声明为
这样在DTD中。如果是ID属性
仅被声明为ID属性
在外部DTD子集中,然后它
将被识别为ID属性
只有XML处理器读取
外部DTD子集。但是,XML
不需要XML处理器
阅读外部DTD,他们可能会
特别是选择不这样做
如果文件被宣布
id()
。
文档只能包含一个文档 一组唯一ID。不可能 独立的独立集合 的ID。
元素的ID只能是 在属性中指定;这不可以 由内容指定 元素或子元素。
ID被限制为XML 名称。例如,它不能包含 空格。
元素最多只能有一个ID。
最多一个元素可以有一个 特别ID。
由于这些限制,XML文档有时包含一个交叉引用结构,该结构未由ID / IDREF / IDREFS属性显式声明。
答案 2 :(得分:1)
XML是对数据的惰性视图。您已经 使用“useHoleWithId”创建了引用。你如何解释和采取行动来获得<hole>
元素取决于你的实现,当然xpath(更改文档的xslt只是实现xpath来实现这一点)是一种强有力的方法。
答案 3 :(得分:0)
你可以改变它:
<xsl:for-each select="my/Drill">
<xsl:variable name="drillid">
<xsl:value-of select="@useHoleWithId"/>
</xsl:variable>
<Drill>
<xsl:attribute name="diameter">
<xsl:value-of select="/my/Holes/Hole[@id=$drillid]/@dia"/>
</xsl:attribute>
<xsl:attribute name="useid">
<xsl:value-of select="$drillid"/>
</xsl:attribute>
</Drill>
</xsl:for-each>
以便Hole
的{{1}}属性显示在Drill
标记