xsl:element must have a value for name - help

I

ina

Hello all,

I am newbie in xml and have a problem with this parse.


I have this xml.file


<Style>
<Strategy>
<Style_Strategy>Geo\Asia</Style_Strategy>
<Style_Strategy>Geo\America</Style_Strategy>
<Style_Strategy>Geo\Europe</Universe>
<Style_Strategy>Sector\America\Cash</Style_Strategy>
</Strategy>
</Style>


and


<?xml version='1.0' encoding='utf-8' ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:eek:utput method="xml" indent="yes"/>


<xsl:template match="/">
<xsl:for-each select="Style/Strategy/Style_Strategy">
<xsl:variable name="new_tag_name"
select="substring-after(.,'Geo\')"/>
<xsl:element name="{$new_tag_name}">
<xsl:value-of select="$new_tag_name"/>
</xsl:element>
</xsl:for-each>
</xsl:template>


</xsl:stylesheet>


I would like to have this as output


<Style>
<Strategy>
<Asia>Asia</Asia>
<America>America</America>
<Europe>Europe</Europe>
<Style_Strategy>Sector\America\Cash</Style_Strategy>
</Strategy>
</Style>


But I have this error: xsl:element must have a value for name
attribute? why?


Ina
 
J

Joris Gillis

Hello all,

I am newbie in xml and have a problem with this parse.


I have this xml.file


<Style>
<Strategy>
<Style_Strategy>Geo\Asia</Style_Strategy>
<Style_Strategy>Geo\America</Style_Strategy>
<Style_Strategy>Geo\Europe</Universe>
<Style_Strategy>Sector\America\Cash</Style_Strategy>
</Strategy>
</Style>


<xsl:template match="/">
<xsl:for-each select="Style/Strategy/Style_Strategy">
<xsl:variable name="new_tag_name"
select="substring-after(.,'Geo\')"/>
<xsl:element name="{$new_tag_name}">
<xsl:value-of select="$new_tag_name"/>
</xsl:element>
</xsl:for-each>
</xsl:template>


</xsl:stylesheet>
But I have this error: xsl:element must have a value for name
attribute? why?

When the element <Style_Strategy>Sector\America\Cash</Style_Strategy> is
processed, $new_tag_name will be empty. Of course it's an error to create
an element without a name... SOmehow, you need to distinguish between the
'Geo' and 'Sector' -situation:

e.g.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:eek:utput method="xml" indent="yes"/>

<xsl:template match="Style_Strategy[starts-with(.,'Geo\')]">
<xsl:variable name="new_tag_name"
select="substring-after(.,'Geo\')"/>
<xsl:element name="{$new_tag_name}">
<xsl:value-of select="$new_tag_name"/>
</xsl:element>
</xsl:template>

<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*" />
</xsl:copy>
</xsl:template>

</xsl:stylesheet>


regards,
 
A

Andy Dingley

ina said:
I would like to have this as output


<Style>
<Strategy>
<Asia>Asia</Asia>
<America>America</America>
<Europe>Europe</Europe>
<Style_Strategy>Sector\America\Cash</Style_Strategy>
</Strategy>
</Style>
But I have this error: xsl:element must have a value for name
attribute? why?

What could an XML element look like without a name? Obviously it's
impossible to have such a thing, so of course XSL should raise an error
in this case.

Secondly, you're generating this name value dynamically and this
suggests that one of your invocations is trying to use an empty string
to do it. In particular, substring-after(.,'Geo\') will return an empty
string if the input string doesn't contain "Geo\" at all (this is a
nuisance in XSLT and needs many <xsl:choose> statements writing)
http://www.w3.org/TR/xpath#function-substring-after

Thirdly I just don't think you should try to do it this way anyway!


I've been writing XSLT for a good while now and I can hardly remember
when I ever used <xsl:element>. This isn't because of anything about
XSLT, it's because of something about XML.

For very complex reasons (very!) XML needs to have a schema produced
before the data. You don't have to write this schema down formally, but
you do need some sort of conceptual view of it. So elements being
created with random unpredictable names are a bad thing in XML, because
they make it hard to process them afterwards. The alternative approach
has been studied in AI work for some years (it's a form of the
"nominals problem") and is known to be both powerful, but very
difficult to work with -- it stops many useful automatic techniques
dead, they just can't process it.

So what does this mean for you? Simply that you should only ever
generate elements with pre-defined names, not ones with names randomly
taken from input data. Of course you can _select_ the name to be used,
based on the input data, but you should still only generate elements
from a small pre-known set of possibles. Then of course if you know
what their possible values are, then you can generate them as literal
result elements in the XSLT, not needing to use <xsl:element>

You have a choice as to whether to write bulky, clear code with literal
elements in the XSLT, probably selected inside different templates or a
big <xsl:choose>. Alternatively you can write a line or two of concise
but unclear code using <xsl:element> and feeding a name parameter
processed out of the strings. Personally I much prefer the first!
What you certainly shouldn't do is to blindly generate element names
that could be anything the input data supplied, and what you simply
can't do is to use it with unreliable string chopping that might return
a simply broken ekement name (such as an empty string)
 
I

ina

Thank you for this explanation. Very helpful.

What I would like to do it is to tag (insert an attribute) with the
style that is corresponding, if it is geographical, sector or whatever
in order to import it to an excel file and be able to do filter from
there.

Ina
 
A

Andy Dingley

ina said:
What I would like to do it is to tag (insert an attribute) with the
style that is corresponding, if it is geographical, sector or whatever
in order to import it to an excel file and be able to do filter from
there.

I wonder if you're trying to do too much with XSLT. XSLT is a
_transform_ tool, to take one document and make other documents from
it. It's not a parser or really a re-formatter. For these quite simple
parse operations you're dealing with here, then you ought to be able to
read them just by parsing. XSLT is useful if you need two different
documents, for different purposes, and having different lifecycles.

If you use XSLT to transform things all over the place, then you have
multiple documents representing basically the same information. This is
obviously a problem to manage them and keep them up-to-date. Simpler to
have one document and just be able to read it from all your different
tools. Try making this more of an XML problem and less of an XSLT
problem.

If you have to use XSLT to transform things regularly, then maybe your
XML schema design isn't as flexible or as easy to use as you might
wish. A single big string of "Geo/America/foo" is really 3 bits of
information, so don't stick them together until you really have to.
You'd probably find it easier to keep this separate in 3 attributes
instead.



PS - you're multi-posting this a lot. I suggest cross-posting each
question just once instead (post to both c.t.x and ms.xml), then we all
get to see the thread afterwards, no matter where each of us is reading
it.
 

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

Forum statistics

Threads
473,754
Messages
2,569,525
Members
44,997
Latest member
mileyka

Latest Threads

Top