I'm trying to design an XML document structure for my application.
I want to store a list of holes like following
<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>
In another part of my document I want to refer to a hole by its id. e.g.
<Drill useHoleWithId='1'/>
When my code finds above <Drill> element I want it to retrieve the values of 'dia' and 'depth' attributes in the <Hole> element that has id='1'.
Of course I can search for a <Hole> element with id equal to the value of 'useHoleWithId' and then get the values of the attributes, but I thought maybe there's a better way to do this using some XML trick. Is there?
PS - Though I don't have any idea about them, may be any of XPath, XLink, XQuery or XPointer could help.
The minOccurs attribute specifies the minimum number of times that the element can occur. It can have a value of 0 or any positive integer. The maxOccurs attribute specifies the maximum number of times that the element can occur.
Techniques you'll need to master: Retrieving information from XML files by using the Document Object Model, XmlReader class, XmlDocument class, and XmlNode class. Synchronizing DataSet data with XML via the XmlDataDocument class. Executing XML queries with XPath and the XPathNavigator class.
In XML, character and entity references are formed by surrounding a numerical value or a name with & and ; —for example, © is a decimal character reference and © is an entity reference.
ref. Optional. Refers to the name of another element. The ref attribute can include a namespace prefix. This attribute cannot be used if the parent element is the schema element.
XPath is certainly one way to do it. An Xpath query to find the hold with id 1 would be something like Holes/Hole[@id="1"]
There is a standard XPath function to reference elements by their "id" attribute.
From the XPath 1.0 spec.:
The id()
function function selects elements by their unique ID
(see [5.2.1 Unique IDs]). When the argument to id
is of type node-set
, then the result is the union of the result of applying id
to the string-value
of each of the nodes in the argument node-set
. When the argument to id
is of any other type, the argument is converted to a string
as if by a call to the string function
; the string
is split into a whitespace-separated list of tokens
(whitespace
is any sequence of characters matching the production S
); the result is a node-set
containing the elements in the same document
as the context node
that have a unique ID
equal to any of the tokens in the list.
id("foo")
selects the element with unique ID
foo
id("foo")/child::para[position()=5]
selects the fifth para child of the
element with unique ID
foo
Another, more generic way of referring to nodes (not only elements) is possible in XSLT. The <xsl:key/>
instruction and the XSLT key()
function are specifically designed for this purpose.
For example, suppose a document contains bibliographic references in the form XSLT, and there is a separate XML document bib.xml containing a bibliographic database with entries in the form:
<entry name="XSLT">...</entry>
Then the stylesheet could use the following to transform the bibref elements:
<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>
Do note, that keys in XSLT overcome the following limitations of the id()
function:
ID attributes must be declared as
such in the DTD. If an ID attribute
is declared as an ID attribute only
in the external DTD subset, then it
will be recognized as an ID attribute
only if the XML processor reads the
external DTD subset. However, XML
does not require XML processors to
read the external DTD, and they may
well choose not to do so, especially
if the document is declared
standalone="yes"
.
A document can contain only a single set of unique IDs. There cannot be separate independent sets of unique IDs.
The ID of an element can only be specified in an attribute; it cannot be specified by the content of the element, or by a child element.
An ID is constrained to be an XML name. For example, it cannot contain spaces.
An element can have at most one ID.
At most one element can have a particular ID.
Because of these limitations XML documents sometimes contain a cross-reference structure that is not explicitly declared by ID/IDREF/IDREFS attributes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With