Can xsl throw an exception when value-of xpath does not exist?

I

inquirydog

Hi-

One frusterating thing for me with xsl is that I don't know
how to make xslt throw some sort of exception when a value-of path
does not exist. For instance, suppose I have the following line in
xslt

<xsl:value-of select="/blah/q" />

and my xml document does not have a node /blah/q. The output would
just leave this part of the document empty. Sometimes this is what I
would like, but often it is indicative of a mistake (for instance, a
spelling mistake in the node name). Spelling mistakes in the xml
document can be caught by a schema or dtd, but ones in the xslt
transformation can not be caught at all (as far as I know). Am I
incorrect? Is there a way to do this? If not, I would suggest that
it be added.

Oh, and I know it *can* be done by using extra coding like
<xsl:if> but this ceratinly isn't an acceptable solution considering
that the node has to be typed in twice in the xslt document therefore
not serving the purpose of testing for spelling mistakes, etc.

thanks
-I
 
A

Andy Dingley

Oh, and I know it *can* be done by using extra coding like
<xsl:if> but this ceratinly isn't an acceptable solution

Stick it in a variable, test the variable, if not empty then output
the variable.
 
R

Robin Johnson

Hi-

One frusterating thing for me with xsl is that I don't know
how to make xslt throw some sort of exception when a value-of path
does not exist. For instance, suppose I have the following line in
xslt

<xsl:value-of select="/blah/q" />

and my xml document does not have a node /blah/q. The output would
just leave this part of the document empty.

This will do it, since you're using value-of and not copy-of:

<xsl:variable name="foo">
<xsl:copy-of select="/blah/q"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="$foo">
<xsl:value-of select="$foo"/>
</xsl:when>
<xsl:eek:therwise>

<xsl:message><!-- set terminate="yes" for termination -->
<xsl:text>WARNING: node was unexpectedly empty</xsl:text>
</xsl:message>

</xsl:eek:therwise>
</xsl:choose>

If /blah/q contained a tree structure you wanted to process further,
you'd need to use exsl:node-set or XSLT 2.0.
 
I

inquirydog

Hi-

Thanks for the response. It is too bad that xslt makes it so
difficult to do these simple checks. If anyone out there who has some
say in the future direction of xslt, I would definitely vote to
somehow add a mode or something that would complain if an xpath
expression doesn't exist. I am trying to debug someone elses xslt
right now and it is very difficult to guess the form that they want
the document in (sure, they could have written a schema to verify
against, but they didn't. At any rate that would be of little use for
typos in the stylesheet).

thanks
-I
 
D

David Carlisle

It is too bad that xslt makes it so
difficult to do these simple checks. If anyone out there who has some
say in the future direction of xslt, I would definitely vote to
somehow add a mode or something that would complain if an xpath
expression doesn't exist.



Why do you find the test

<xsl:if test="not(/a/b/c)">
there is no /a/b/c/ element
</xsl:if>

hard to use? what syntax would you have in mind that would be more
direct than this?

David
 
R

Robin Johnson

Thanks for the response. It is too bad that xslt makes it so
difficult to do these simple checks.

Without meaning to be evangelical, but it looks simple enough to me
once you get used to the look and feel of XSLT.
If anyone out there who has some
say in the future direction of xslt

(Just to make it clear, I have no such say.)
I would definitely vote to
somehow add a mode or something that would complain if an xpath
expression doesn't exist.

The problem there is, how do you define an XPath expression that
"doesn't exist?" All XPath expressions 'exist' except syntactically
invalid ones (which do indeed cause the processor to complain), they
just sometimes point to empty node-sets. It's easy to test whether a
node-set expression is empty by slapping an if or a choose round it.

(True, this sort of thing becomes a fair bit easier when you have a
proper tree-fragment data type, as in EXSLT or XSLT 2.0.)
I am trying to debug someone elses xslt
right now and it is very difficult to guess the form that they want
the document in (sure, they could have written a schema to verify
against, but they didn't.

Job security, I guess. Can you find any samples of input xml documents
lying around?
At any rate that would be of little use for typos in the stylesheet).

Well, I don't personally think it's the job of the implementor of a
programming language to protect you from other people's ambiguous
typos, but your mileage may vary.
 
A

Andy Dingley

It is too bad that xslt makes it so
difficult to do these simple checks.

XSLT syntax is _meant_ to be difficult. It's not for humans to write,
it's for machines to write. The original "grand plan" involved much
smarter editors and CASE tools which hid the admitted lumpiness of the
line-by-line syntax away from the users.

I would definitely vote to
somehow add a mode or something that would complain if an xpath
expression doesn't exist.

This is really bad and wrong. The values of XPath expressions don't
"not exist", they evaluate to empty sets. If you think about the
programming environment in the right way, as a calculus, then this is
the obvious way to do things. And you _have_ to think about XSLT the
right way, for if you don't , then it will bite you.
 
R

Robin Johnson

XSLT syntax is _meant_ to be difficult. It's not for humans to write,
it's for machines to write. The original "grand plan" involved much
smarter editors and CASE tools which hid the admitted lumpiness of the
line-by-line syntax away from the users.

Which was, in my opinion, rather misguided; you can't make programming
easy by sticking on a nice front-end. Programming is hard because
precise thought is hard, not because you have to remember a lot of
keywords and syntax.

Still, the 'lumpiness' of the XML syntax makes it easy to navigate
your program structure... once you're used to it. My only major gripe
with the syntax is that comments can't be nested, which can make
debugging a bit cathedralgic (script-like # comments as a processor
extension anyone?)
 
I

inquirydog

Why do you find the test

<xsl:if test="not(/a/b/c)">
there is no /a/b/c/ element
</xsl:if>


For starters, it is redundant. There should be a way to do
the test without having to retype the xpath expression in twice (it
may be simple to do for your simple /a/b/c example, but less so with
an xpath expression that is a few hundred characters with interesting
combinations of operators and functions).

Also, it puts the burden on the programmer to remember to do
the test. If you are trying to manage a large group of xslt
programmers, you have to double check that each is actually making the
check.

Third, it doesn't actually stop the processing. In a large
transformation, the error message would be placed somewhere in the
output, which might not be noticed for some time.

Forth, If someone unfamiliar with the project has to make a
change to the xpath expression, it would be natural for them to search
and find the expression, change it, and never notice the redundant
check above. This bug could be not noticed for some time.

Fifth, it would blow up the size of many transformations quite
a bit (the test is typically twice the size of the original code).

Sixth, even if you use a variable to store the condition, you
have to invent a series of variable names to store the expressions.
In an xslt transformation with 40 xpath expressions you need 40
variables. You also need to invent the name of 40 variables.
Probably you will name them something like xpath1, xpath2, etc. It
would be easy to accidentally use xpath4 when you meant to use xpath6,
or something like that. And what do you call a new xpath that gets
sandwitched between xpath7 and xpath8?

hard to use? what syntax would you have in mind that would be more
direct than this?


Could be many things. Perhaps a global processing directive that
changes the default to expecting that a value-of be non-empty, or to
exactly contain one item. Perhaps an extra attribute in a value-of to
expect this (complainIfEmpty="true").

I am also aware that validation is really in the category of
schamas, so to be in line with the xml philosophy, perhaps what is
needed is a way to convert xslt transformations to schemas (this would
be done by an xslt transformation itself), which could be used to
prevalidate xml that will be processed by the original xslt
transformation.

Or to be completely radical here, why not make the default
behavior of xslt to expect non empty xpath expressions in value-of?
Certainly this isn't always what you want, but I would be willing to
bet that more than often it is what is desired.

I just want a way to make my envalope addressing xslt look
like this

<xsl:value-of select="name" />
<xsl:value-of select="address" />

without having to blow this up with ugly redundant checks 90% of the
time.

thanks
-I
 
I

inquirydog

Greetings-
Without meaning to be evangelical, but it looks simple enough to me
once you get used to the look and feel of XSLT.

I actually am experienced with the whole xslt paradigm. Been
writting for some time now.

The problem there is, how do you define an XPath expression that
"doesn't exist?" All XPath expressions 'exist' except syntactically
invalid ones (which do indeed cause the processor to complain), they
just sometimes point to empty node-sets. It's easy to test whether a
node-set expression is empty by slapping an if or a choose round it.

When I used the phrase "doesn't exist" I thought it was clear
that I meant nodesets of size zero. In some circumstances, any node
size not equal to one should be considered a problem.

I am claiming that a check of this type is typically necessary
to write foolproof scripts.

Job security, I guess.

The script is open source actually.
Can you find any samples of input xml documents
lying around?

I looked, and found none. Eventually I had to put in all
sorts of debug information line by line to find the problems in my
xml.
Well, I don't personally think it's the job of the implementor of a
programming language to protect you from other people's ambiguous
typos, but your mileage may vary.

I couldn't disagree with you more. If a config file is
missing an important value, the program should comlain and refuse to
start. If a web service recieves a malformed request, it should
refuse to process it (think of security alone).

Right now from what I can see there is no good way to do this
with xslt.

thanks
-I
 
I

inquirydog

It is too bad that xslt makes it so
XSLT syntax is _meant_ to be difficult. It's not for humans to write,
it's for machines to write. The original "grand plan" involved much
smarter editors and CASE tools which hid the admitted lumpiness of the
line-by-line syntax away from the users.

I can accept this, but then I need that grander technology.
So far I am unaware of a good solution to the problem I mentioned. In
practice xslt is being written by hand right now. It is a very
successful technology (arguably the only majorly succesful xml
technology around today, but that is opening a can of worms), and the
way it is being used probably won't change for some time. People need
solutions now, and until xslt can address this problem it will be left
out of considerations for many projects.
This is really bad and wrong. The values of XPath expressions don't
"not exist", they evaluate to empty sets. If you think about the
programming environment in the right way, as a calculus, then this is
the obvious way to do things. And you _have_ to think about XSLT the
right way, for if you don't , then it will bite you.

As mentioned in a response above, I thought I was being clear
when I used the phrase "not exists" I really meant node set size=1,
but I guess by the double response about this that it wasn't so clear.
The point is that it is very common to want to check for the unique
existance of a value-of item. If you would like to address your mail,
you would use the following transformation

<xsl:value-of select="name" />
<xsl:value-of select="address" />

and if the original xml is missing the name or address, or if they
appear more than once, you would like to know. Without redundancy or
much extra work (which will kill a group project) this is impossible
with xslt as it stands. This will preclude xslt from many projects
until either modifications are made, or until the appropriate big
picture technology is written around xslt.

Looking forward I believe that xslt (or similar technology) it
the right way to do many things, so it is unfortunate it it is missing
something so basic right now.

thanks
-I
 
D

David Carlisle

You may prefer XSLT2 (draft, as implemented so far just in saxon8) this
allows you to specify the expected type of expressions and you'll get a
type casting error if teh returned expression doesn't have the right
type (eg it's empty)

David
 
P

Patrick TJ McPhee

% For starters, it is redundant. There should be a way to do
% the test without having to retype the xpath expression in twice (it

How about putting the results of the expression in a variable and
testing that? Sure, the programmer will have to do it, but I guess
the programmer has to get something right somewhere along the line.
Surely you don't want your entire process to be dependent on every
XPath expression returning data.

You can use xsl:message with terminate='yes' to have the script exit
immediately.

Now, you're probably right that there's a deficiency here, but unless
you come up with a concrete, workable syntax that resolves your specific
problem, it's difficult to discuss its merits.
 
M

Magnus Henriksson

--snip--
The point is that it is very common to want to check for the unique
existance of a value-of item. If you would like to address your mail,
you would use the following transformation

<xsl:value-of select="name" />
<xsl:value-of select="address" />

and if the original xml is missing the name or address, or if they
appear more than once, you would like to know.

--snip--

Sorry for getting into this thread so late...

As far as I can tell, you want to check if an XPath expression evaluates to
an empty node set, and if so, report this as an error. To me, this is the
job of a schema (XML Schema, DTD, Relax, ...). If you do not have a schema,
all bets are off, and you need to check the conditions yourself, in the
stylesheet or in another way. Personally, if I would need to transform an
XML document without a schema, I would do some basic checks using Schematron
(or a custom stylesheet), before transforming.

What I am trying to say is that I think it is necessary to separate the
transformation from the "validation".


// Magnus
 
R

Robin Johnson

[email protected] (inquirydog) wrote in message news: said:
So far I am unaware of a good solution to the problem I mentioned.

Honestly, I can't see what's not 'good' about sending the result of
the expression into a variable and then testing that variable; exactly
as if you wanted to check that, for example, a numeric expression
didn't evaluate to zero.

Can you write a schema for your input documents, and validate them
against that before running the stylesheet?
 
I

inquirydog

Magnus Henriksson said:
Sorry for getting into this thread so late...

As far as I can tell, you want to check if an XPath expression evaluates to
an empty node set, and if so, report this as an error. To me, this is the
job of a schema (XML Schema, DTD, Relax, ...). If you do not have a schema,
all bets are off, and you need to check the conditions yourself, in the
stylesheet or in another way. Personally, if I would need to transform an
XML document without a schema, I would do some basic checks using Schematron
(or a custom stylesheet), before transforming.

What I am trying to say is that I think it is necessary to separate the
transformation from the "validation".

I fully agree with this in theory. The problem is that given
the way that schemas and xsl work today this solution is very flawed.
Most of the problems that I mentioned above are still not fixed. For
instance, the xpath expression must be expressed somehow redundantly
(in the transformation and in the schema). This is a big problem if
there is a typo in the xslt transformation- ie my schema makes sure
that I have an element called <dogname>, but the transformation tries
to use <dawgname>. Oops! Now my results are incorrect and no one is
there to tell me about it. Second, someone might change the
transformation and forget to change the schema. Again trouble. Third
it requires the developer to do much extra work for simple things.

Modularity in schemas vs transformations would probably be a
good thing in the final solution to this problem, but as it stands
today the present solution isn't very useful.

thanks
-I
 
I

inquirydog

How about putting the results of the expression in a variable and
testing that? Sure, the programmer will have to do it, but I guess
the programmer has to get something right somewhere along the line.
Surely you don't want your entire process to be dependent on every
XPath expression returning data.

Definitely not! But there needs to be a simple way to test
for the existence of data for the cases that you need to, which I
think would be often.
You can use xsl:message with terminate='yes' to have the script exit
immediately.

I didn't know about that. That is quite useful to know
actually (solves part of the problem).
Now, you're probably right that there's a deficiency here, but unless
you come up with a concrete, workable syntax that resolves your specific
problem, it's difficult to discuss its merits.

I don't know what was not concrete about the solutions I mentioned
earlier
Could be many things. Perhaps a global processing directive that
changes the default to expecting that a value-of be non-empty, or to
exactly contain one item. Perhaps an extra attribute in a value-of to
expect this (complainIfEmpty="true").

but at any rate I've thought about it some more and have another
perhaps better solution. What about inventing new elements like
value-of with type checking in them, like

<xsl:unique-value-of select="xpath expression"> (checks for
one and only one node in the node set).

and other common patterns

<xsl:value-of-list select=xpath expression" separator=",">
(prints out a list of nodes separated by the separator, checks that
the list has at least one element)

<xsl:apply-unique-template select="xpath expression"> (works
like xsl:apply-templates, but checks that the node set is of length
one).

<xsl:list-apply-template separator="," select="xpath
expression"> (works like xsl:apply-templates, but checks that the node
set has one or more elements, and puts the separator between the
outcomes of the apply templates).

thanks
-I
 
I

inquirydog

Honestly, I can't see what's not 'good' about sending the result of
the expression into a variable and then testing that variable; exactly
as if you wanted to check that, for example, a numeric expression
didn't evaluate to zero.

Sure, I *could* just write the whole thing on a universal
Turing Machine and get the same results, but why would I want to. In
many cases to do the value-of properly the work needed to do that will
be so great that most people will not do it, and as a consequence most
xslt transformations will not be written to a reasonable enough
quality that they will be used in the business community.

I was going to write a simple example of a transformation
written with just value-of vs full out properly to show you the amount
the proper way would bulk it out, but decided I don't even want to do
that. XSLT right now makes certain checks very difficult.
Can you write a schema for your input documents, and validate them
against that before running the stylesheet?

See email above.

thanks
-I
 
R

Robin Johnson

On 27 Aug 2004 14:40:05 -0700, (e-mail address removed) (inquirydog)
wrote:
[...]
This is a big problem if
there is a typo in the xslt transformation- ie my schema makes sure
that I have an element called <dogname>, but the transformation tries
to use <dawgname>. Oops! Now my results are incorrect and no one is
there to tell me about it.

Yes, if you type the wrong code, you'll get the wrong results.

I can't think of a language that doesn't have that 'limitation'.
 
I

inquirydog

Robin Johnson said:
On 27 Aug 2004 14:40:05 -0700, (e-mail address removed) (inquirydog)
wrote:
[...]
This is a big problem if
there is a typo in the xslt transformation- ie my schema makes sure
that I have an element called <dogname>, but the transformation tries
to use <dawgname>. Oops! Now my results are incorrect and no one is
there to tell me about it.

Yes, if you type the wrong code, you'll get the wrong results.

I can't think of a language that doesn't have that 'limitation'.

Actually, I can't think of a language which doesn't catch typos-

-----

c:

printq("you dude\n");

compilation result:

In function `main':
: undefined reference to `printq'
collect2: ld returned 1 exit status

---

perl:

x = x + &;

run result:

line 4: syntax error near unexpected token `;'
line 4: ` x = x + &;'

---

java:

static public void main(String args[])
{

File file = new File("qq");

file.createNewFile();

}

compilation:

test.java:13: unreported exception java.io.IOException; must be
caught or
declared to be thrown
file.createNewFile();
^
1 error

(one of the reasons that I love Java is because it is great at compile
time error checking, finding perhaps 90% of my bugs right off the bat)

---

I am merely requesting that xslt have the same error checking
capabilities as just about every other language out there (it does in
some ways, but I am pointing out what I consider to be a large
ommision in the language). Using a schema to check that address.xml
has a <street> element in it like this

<xsd:element name="street" type="xsd:string" />

and using an xslt transformation with the following typo

<xsl:value-of select="name" />
<xsl:value-of select="stret" /> <-- typo, should be street
<xsl:value-of select="city" /> <xsl:value-of select="state" />
<xsl:value-of select="zipcode" />

would contain an error that should be but is not caught by the xslt
translation software. Granted, as some have pointed out here, you can
store all xpath expressions in a variable, do a test with instructions
to complain and stop processing, and then use the value-of with the
variable, but given that 1). Most people won't do this, and 2). It
could increase the size of many otherwise simple transformations by
probably double (ie- consider how big my simple example above would
become), I don't think this is a reasonable way to do things.


I believe that xslt is the way of the future of development, and am
eager to patch all the holes and growing pains that all new
technologies experience. I've given some of what I believe are
reasonable suggestions about how I think that should be done, if you
have a tangible reason why you think they are a bad idea, I would love
to listen. I am not sure how essentially saying -all languages have
problems- and throwing up your arms moves xslt forward.

thanks
-I
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,997
Messages
2,570,240
Members
46,830
Latest member
HeleneMull

Latest Threads

Top