There may be times when you wish to use an LXP variable value within the contents of an HTML tag. For example, you may
have a graphic with a dynamically assigned width. Since LXP only performs variable value substitution within LXP tags, you
cannot substitute an LXP variable within an HTML tag as you would with an LXP tag. In other words, the
$width variable reference in the following example will not work:
<lxp>
<!-- WRONG: LXP variable will not be substituted in non-LXP tag -->
<img src="/images/spacer.gif" width="$width" />
</lxp>
You might think an obvious solution would be to place the LXP <putvar> tag
inside of the HTML tag. There is a problem with this approach, however. Specifically, such syntax breaks the integrity of
the mark-up of the document. For a mark-up language to be
well formed
, tags must not be nested within
the actual contents of another tag as shown in this example:
<lxp>
<!-- Not recommended: Tags should not be nested in one another -->
<img src="/images/spacer.gif" width="<putvar name="width" />">
</lxp>
Note that nesting LXP tags within non-LXP tags can work in some circumstances, though it is not recommended. The LXP
well-formedness requirements will probably grow more stringent in the future, and this kind of nesting is an easy way to
make your LXP mark-up both lose its readability, as well as its mark-up integrity.
The LXP solution to this problem is the <xtag> element. The
<xtag> is used as a wrapper to display any foreign (non-LXP) tag. It has one required
attribute, which is xname. This attribute determines what tag will be output in place of
<xtag> when the <xtag> is processed by LXP. For
example, <xtag xname="a"> will be displayed as
<a>.
Optionally, the xappend attribute may be used to append an arbitrary character string
to the end of the generated tag. For example, using xappend=" checked" for an HTML checkbox
input tag will create an <input type="checkbox" checked> tag.
Any other attributes will be passed through to the wrapped tag, directly. This is the key to the usefulness of the
<xtag>, because variable values may be substituted within an
<xtag>, and are then directly embedded within the resulting foreign tag. As an
example, the correct way to wrap an HTML <img> tag in LXP is shown in Example 13-31.
Example 13-31. Using <xtag> for empty elements
<lxp>
<xtag xname="img" src="images/spacer.gif" width="$width" />
</lxp>
Here is the displayed output from this document, once processed by LXP, assuming that the width variable has a value of 10:
<img src="images/spacer/gif" width="10" />
Notice the trailing slash used in the <xtag> element within Example 13-31. An <xtag> may be an opening, closing, or empty-element tag,
depending on what tag you ultimately wish to display. A vital nuance to the nature of
<xtag> is that LXP
keeps track
of what opening
<xtag> elements have been left open, and chooses the appropriate tag name to use when
it reaches a closing </xtag>.
If you are wrapping a foreign tag that does not close (e.g., the HTML <img>
tag), you
must
adhere to document strictness and make that <xtag>
an empty-element tag with a trailing slash. If you do not, LXP will name the next
closing </xtag> with the xname assigned to the last
opening <xtag> (e.g., img), which in this case will
result in mismatched tag output.
Consider the following piece of mark-up:
<lxp>
<xtag xname="table" width="$table_width">
<tr>
<-- WRONG: The following Empty-element requires trailing slash -->
<td><xtag xname="img" src="images/spacer.gif" width="$width"></td>
</tr>
</xtag>
</lxp>
This code uses three <xtag> elements; one opening and one closing (corresponding
to a wrapped <table> element), and one opening
<xtag> used to wrap an <img> tag. Since the
<img> tag does not have a closing tag in HTML, this
<xtag> should instead be an empty-element tag, but it will not be read that way by LXP
(notice the lack of a trailing slash). The problem with this mark-up is that since LXP keeps track of open
<xtag> elements, when it reaches the first
closing</xtag>, it expects to close not the
intended<table> tag, but the <img> tag.
Assuming the table_width variable has a value of 100,
and the width variable has a value of 10, the incorrect
output looks like this:
<table width="100">
<tr>
<-- WRONG: Empty-element requires trailing slash -->
<td><img src="images/spacer.gif" width="10"></td>
</tr>
</img>
Example 13-32 shows the correct way to mix opening, empty-element, and closing
<xtag> elements.
Example 13-32. Using nested <xtag> elements
<lxp>
<xtag xname="table" width="$table_width">
<tr>
<-- RIGHT: Empty-element has required trailing slash -->
<td><xtag xname="img" src="images/spacer.gif" width="$width" /></td>
</tr>
</xtag>
</lxp>
Since the second <xtag> element in Example 13-32 uses
a trailing slash, as is required when you wrap a tag that does not explicitly close, LXP does not anticipate a closing tag
for the <img> tag, and the output looks (correctly) like this:
<table width="100">
<tr>
<-- RIGHT: Empty-element has required trailing slash -->
<td><img src="images/spacer.gif" width="10" /></td>
</tr>
</table>