Namespaces, Name With Spaces, and Attribute Values
October 8, 2003
Q: What namespace prefix should I use in a W3C Schema?
Although the W3 Schema specification uses the namespace prefix
xsd:, it looks
as though in current practice only
xs: is used.
Could you please confirm if this is the case and is the reason just that it is shorter?
A: Actually, it depends on which part of "the W3 Schema specification" you're referring to
- XML Schema Part 0: Primer does indeed
xsd:namespace prefix. (For instance, see the sample Purchase Order Schema.)
- However, that namespace prefix is nowhere to be found in the main XML Schema Part 1: Structures, which uses
- And XML Schema Part 2: Datatypes uses
xsd:in the examples, but
xs:for its Appendix A, the normative Schema for Datatype Schemas.
What's going on here? Isn't one prefix the right one?
While one might wish for more consistency in the specs to avoid this sort of confusion, in fact there's no such thing as a "correct" W3C Schema namespace prefix or even simply a better one. Indeed, there's no such thing as a correct or even better namespace prefix for any XML application at all. That's because XML processing software -- at least, software which conforms to the Namespaces in XML Recommendation -- doesn't care about the prefix; it cares only about what URI the prefix is associated with. The prefix is just a shorthand way of referring to the URI.
Assume an XML document, presumably a W3C Schema document, opens in this fashion:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> ... <xs:element name="elem1" type="Address">
When the processor encounters the
xs:element element, it actually
"understands" it in something like this form, substituting the URI for the prefix:
This notation -- the namespace URI enclosed in curly braces, followed by the element's local name -- is used internally almost universally by XPath-aware processors, such as XSLT engines. If you think about it, you'll see that it thus really doesn't matter what prefix you use, as long as you choose one which isn't misleading to a human reader and then use it consistently. For instance, you might rework the partial XML document (Schema) above as follows:
<W3CSchema:schema xmlns:W3CSchema="http://www.w3.org/2001/XMLSchema"> ... <W3CSchema:element name="elem1" type="Address">
If it doesn't make any difference which prefix we use, why choose one prefix over
I don't know, but suspect, that use of the
xs: prefix might allude to a predecessor of XML Schema, known as
XSchema, later renamed the Document Definition Markup Language (DDML).
And, as you suggest, it does save a character for every namespace-qualified name.
other hand, simply using
x: would be even shorter, just not as clear. As for
xsd:, maybe it's meant to associate the namespace with the filename
extension, ".xsd", commonly used for XML Schema
So, sure, go ahead, use
xs: for brevity's sake,
xsd: if you want
to associate the namespace prefix with the Schema document's extension, or anything
Just keep the URIs correct, and keep the namespace prefix meaningful and consistent.
Q: How do I ignore elements or attributes in a particular namespace?
What is the best approach to copy only elements and attributes in namespace "a" and ignore everything in namespace "b", using XSLT? For instance, in this document,
<a:root xmlns:a="a" xmlns:b="b" > <a:child name="attr1" b:foo="foo1" /> <a:child name="attr2" b:foo="foo2" /> </a:root>
I'd like to copy the
a:child elements, as well as the
name attribute of each
a:child, but ignore the
A: I'm not sure if this is the "best" approach -- it's not particularly
elegant -- but a straightforward way to do it is simply to select only those element
attribute names that do not start with the "undesirable" namespace prefix. This requires
that you use the XPath
name() function, in concert with the
starts-with() functions. Here's a pair of
elements to do so might look something like this (substituting an XHTML result tree
copy operation, for demonstration purposes):
<xsl:template match="*|@*[not(starts-with(name(), 'b:'))]"> <h3>Copying <xsl:value-of select="name()"/>...</h3> <xsl:apply-templates select="*|@*[not(starts-with(name(), 'b:'))]"/> </xsl:template> <xsl:template match="@*"> <h4>Copying <xsl:value-of select="name()"/>...</h4> </xsl:template>
Note that you can't use the
local-name() function, which strips off the
namespace prefixes. You also can't use the
namespace-uri() function to test for
the desirable namespace prefix: you won't pick up (in this case) the
Q: Can a parameter name include a space?
I need to declare some XSLT parameter with whitespace in the name. Is this
<xsl:param name="my value" />
A: No. Parameter names must be legitimate XML names. A simple attribute
value, even that of an
name attribute, may
contain whitespace and be perfectly well-formed as XML . But
xsl:attribute, is intended to create a unique,
easily parsed instance of an object in a document. That a parameter's name, once created,
later referred to using a dollar sign -- like
$my_value, say -- rather than
enclosed in angle brackets is only superficially different from the name of an element
attribute. Like any other programming language, XSLT simply does not allow spaces
names of identifiers used by programs written in that language.
The whole point of XML is to simplify markup by eliminating as many options as possible. Nearly every XMLoid has a wish list of Things XML Might Do For My Convenience. But the XML world is complicated enough without trying to satisfy everyone. In my opinion, core XML remains a model of how to do something good enough. So you're stuck; either reevaluate your need or consider some non-XML solution.
Q: How do I build an attribute value in XSLT using a variable value?
I don't mean "variable" in the sense of an XSLT variable. I mean the actual value isn't known until runtime, taken (say) from an element's value. For instance, if I want to put this in the output:
and the number of points is available as an element value elsewhere in the document, how do I substitute it in place of the "some-value-in-points"?
A: The only real trick is to know that an XSLT stylesheet can build
attributes not just using literal values, but by way of a special XSLT element,
Assume you've got a source document which looks like this (ignoring whitespace added for legibility):
<root> ... <textwidth>150</textwidth> ... </root>
Also assume that there's only one
textwidth element in this document. In a
template rule in the stylesheet, you'd include something like this:
<input> <xsl:attribute name="style">width:<xsl:value-of select="/root/textwidth" />pts</xsl:attribute>... </input>
Also in XML Q&A
xsl:attribute element must immediately follow the element you want to
assign the attribute to -- the input element, in this case. It takes a name attribute,
the resulting attribute will have the indicated name. The string-value of the
xsl:attribute element is assigned as the resulting attribute's value. In the
above example, we've instantiated (a) an
input element, which has (b) a
style attribute the value of which is the concatenation of the text string
"width:", the string-value (150) of the source document's
and the text string "pts". Thus:
By the way, note that you needn't get the value to be substituted from the source
can get it from another document altogether, using the
document() function. And
this other document can even be the stylesheet itself, if that's what you're after:
supply an empty string as the argument to the function: