Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > XML > Identity transformation problems

Reply
Thread Tools

Identity transformation problems

 
 
Bilal
Guest
Posts: n/a
 
      09-25-2006
Hello,
I'm attempting to "populate" an template XML file with some data using
identity transform (approach suggested by Joe K.; Thanks! and have
come across some strange behaviour using XMLSpy, AltovaXML, and
xsltproc. The actual stylesheets are to be auto-generated by another
stylesheet (that process I've worked out! and now troubleshooting
these generated stylesheets in XMLSpy's XSL debugger. So I'm wondering
if my approach is basically wrong to elicit the unexpected behaviour,
rather than that the apps are buggy. So here goes:

The transformation stylesheet is:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlnssl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/message/Control/Trace/Id">
<xsl:attribute name="extension">bbb-999</xsl:attribute>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

nothing fancy except that I'm trying to put/add value to the
"/message/Control/Trace/Id/@extension" attribute and the xml to be
transformed is:

<?xml version="1.0" encoding="ISO-8859-1"?>
<message>
<id>Text</id>
<creationTime>Text</creationTime>
<versionCode/>
<Id>Text</Id>
<processingCode/>
<processingModeCode/>
<acceptCode/>
<commRcv>
<device>
<id extension="Old_Ext">Text</id>
</device>
</commRcv>
<commSnd>
<device>
<id>Text</id>
</device>
</commSnd>
<Control>
<author>
<Entity>
<id>Text</id>
<code/>
<Organization>
<id>Text</id>
</Organization>
</Entity>
</author>
<Trace>
<Id extension="OLD">Text</Id>
<person>
<value/>
<Text>String</Text>
</person>
<birthTime>
<value>Text</value>
<Text>String</Text>
</birthTime>
<name>
<value>Text</value>
<Text>String</Text>
</name>
</Trace>
</Control>
</message>

I'm unsure if I am doing anything illegal as far as XSL/T etc. is
concerned but here are the results:

XMLSpy + AltovaXML add the attribute to /message/Control/Trace instead,
and the /message/Control/Trace/Id element isn't created at all.

xsltproc:
Gives the error "xsl:attribute: Cannot add attributes to an element if
children have been already added to the element." That is very odd since
the /message/Control/Trace/Id/ element doesn't have any children!

I've tried various permutations of the stylesheet as follows:

Trial #1: Populate attribute & element
<xsl:attribute name="extension">bbb-999</xsl:attribute>
<xsl:elementname="Id">xsl-123456789</xsl:element>

XMLSpy/AltovaXML add the extension to the parent /message/Control/Trace
element and the "Id" element isn't created. xsltproc errors as before.

Trial #2: Populate element & attribute
<xsl:elementname="Id">xsl-123456789</xsl:element>
<xsl:attribute name="extension">bbb-999</xsl:attribute>

XMLSpy/AltovaXML add/populate the "Id" element correctly but the
"extension" attribute is missing. xsltproc errors as before.

Trial #3: Populate element
<xsl:elementname="Id">xsl-123456789</xsl:element>

Value for "Id" element is add without problem by all.

Trial #4: Two seperate templates
This was my original approach but didn't work (see below). Created two
seperate template, one for the element and one for the attribute:

<xsl:template match="/message/Control/Trace/Id/@extension">
<xsl:attribute
name="extension">bbb-999</xsl:attribute> </xsl:template>
<xsl:template match="/message/Control/Trace/Id">
<xsl:element name="queryId">xsl-123456789</xsl:element>
</xsl:template>

The template for the "Id" element is actioned while the one for the
"Id/@extension" attribute never is; unsure why the xslt processor never
'runs' the template for the


So what am I doing wrong??? Is there a better/proper way to populate
both the element and its attribute?

Would aoppreciate any suggestions!

Regards,

Bilal B.



*** Sent via Developersdex http://www.developersdex.com ***
 
Reply With Quote
 
 
 
 
Martin Honnen
Guest
Posts: n/a
 
      09-25-2006


Bilal wrote:


> <xsl:template match="/message/Control/Trace/Id">
> <xsl:attribute name="extension">bbb-999</xsl:attribute>
> </xsl:template>


That does not work out, if you want to add an attribute to that element
then you need to first copy the element

<xsl:template match="/message/Control/Trace/Id">
<xsl:copy>
<!-- use that if you have other attributes to copy -->
<xsl:apply-templates select="@*"/>
<xsl:attribute name="extension">bbb-999</xsl:attribute>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>


--

Martin Honnen
http://JavaScript.FAQTs.com/
 
Reply With Quote
 
 
 
 
Bilal
Guest
Posts: n/a
 
      09-25-2006
Hi Martin,
Many thanks!! That works for adding/setting the attribute but what if
the element's value is also being set simultaneously?

Regards,

Bilal



*** Sent via Developersdex http://www.developersdex.com ***
 
Reply With Quote
 
Martin Honnen
Guest
Posts: n/a
 
      09-25-2006


Bilal wrote:


> That works for adding/setting the attribute but what if
> the element's value is also being set simultaneously?


Well once you write a template for that element it is up to you to fill
the template with instructions as needed, the xsl:copy will only copy
the element itself, the <xsl:apply-templates select="@*"/> (and the
other template you had) take care of copying existing attributes, the
<xsl:attribute name="extension">bbb-999</xsl:attribute> adds the new
attribute, and the <xsl:apply-templates/> lets the XSLT processor
process the existing child nodes. If you don't want any of those steps
then remove or replace them e.g.

<xsl:template match="/message/Control/Trace/Id">
<xsl:copy>
<!-- use that if you have other attributes to copy -->
<xsl:apply-templates select="@*"/>
<xsl:attribute name="extension">bbb-999</xsl:attribute>
<xsl:text>Kibology for all</xsl:text>
</xsl:copy>
</xsl:template>

will not process the child nodes but simply add that (example) text as a
child node.

--

Martin Honnen
http://JavaScript.FAQTs.com/
 
Reply With Quote
 
Bilal
Guest
Posts: n/a
 
      09-26-2006
Hi Martin,
Thanks for the explanation and the example. Unfortunately, I still
don't have a full understanding about the 'precedence' of how the
templates are applied, and hence in my not-so-infiite wisdom, I was
trying to use the code below (note the xsl:element tag instead of the
xsl:text tag) to put value in the Id element itself, and kept on
wondering why it was adding an new element /message/Control/Trace/Id/Id
instead

<xsl:template match="/message/Control/Trace/Id">
<xsl:copy>
<!-- use that if you have other attributes to copy -->
<xsl:apply-templates select="@*"/>
<xsl:attribute name="extension">bbb-999</xsl:attribute>
<xsl:element name="Id">Kibology for all</xsl:element>
</xsl:copy>
</xsl:template>

Just to take this one step further, what would be the right way to copy
the children below /message/Control/Trace/Id using the default template?

<xsl:template match="/message/Control/Trace/Id">
<xsl:copy>
<!-- use that if you have other attributes to copy -->
<xsl:apply-templates select="@*"/>
<xsl:attribute name="extension">bbb-999</xsl:attribute>
<xsl:text>Kibology for all</xsl:text>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>

This appears to do the trick (I think) but what it ALSO does is copy the
old text value (child?) AFTER inserting the new text value, as well as
copying any remaining child elements.
How would one achieve copying the new text value/child, avoid copying
the old text value/child, but copy any child elements?

Lastly, any recommendations on good XSL resources/books other then
obvious ones on the web? I think I'm reaching the limits of my
self-learned XSLT knowledge.

Regards,

Bilal B.

*** Sent via Developersdex http://www.developersdex.com ***
 
Reply With Quote
 
Martin Honnen
Guest
Posts: n/a
 
      09-26-2006


Bilal wrote:


> Unfortunately, I still
> don't have a full understanding about the 'precedence' of how the
> templates are applied, and hence in my not-so-infiite wisdom, I was
> trying to use the code below (note the xsl:element tag instead of the
> xsl:text tag) to put value in the Id element itself, and kept on
> wondering why it was adding an new element /message/Control/Trace/Id/Id
> instead
>
> <xsl:template match="/message/Control/Trace/Id">


You have a template here for Id elements with parent Trace with parent
Control with parent message as the root element, then in that template
you do

> <xsl:copy>


meaning that Id element is copied. If you don't want to copy those Id
elements then don't use xsl:copy in this template. But if you want to
have attributes like that extension attribute you first need an element
to add it to.


> How would one achieve copying the new text value/child, avoid copying
> the old text value/child, but copy any child elements?


Sorry, in my understanding you can't "copy" "new" values or children,
"new" stuff can only be added.
As for copying only child _elements_ but not child _text_ nodes simply
do e.g.
<xsl:apply-templates select="*"/>
instead of
<xsl:apply-templates/>
in the template where you want to do that. For the rare case that you
also have comment nodes or processing instruction nodes that need to be
copied like the elements then do e.g.
<xsl:apply-templates select="node()[self::* or self::comment() or
self:rocessing-instruction()]"/>




--

Martin Honnen
http://JavaScript.FAQTs.com/
 
Reply With Quote
 
Joe Kesselman
Guest
Posts: n/a
 
      09-26-2006
Bilal wrote:
> don't have a full understanding about the 'precedence' of how the
> templates are applied


There are almost no precedence rules, unfortunately. If you've got a
possible conflict, you should probably make your precedence explicit by
adding the priority attribute to the templates in question.

> How would one achieve copying the new text value/child, avoid copying
> the old text value/child, but copy any child elements?


One solution: Change the select in the second apply-templates so it
matches only elements. "*" will work, since the implied axis is child
and the principal node type of that axis is element. If you wanted to
accept other kinds of non-text nodes you might want to enhance that a
bit, eg "*|comment()".

Another solution would be to use a mode, but that's a bit more
complicated to explain if you aren't already familiar with them.

> Lastly, any recommendations on good XSL resources/books other then
> obvious ones on the web? I think I'm reaching the limits of my
> self-learned XSLT knowledge.


I haven't looked at what's come out recently. Mike Kay's tome is still
the best XSLT reference manual out there, I think, but if you're looking
for a tutorial you'll want something else as well.

--
() ASCII Ribbon Campaign | Joe Kesselman
/\ Stamp out HTML e-mail! | System architexture and kinetic poetry
 
Reply With Quote
 
Bilal
Guest
Posts: n/a
 
      09-27-2006
Hi Joe and Martin,
Thanks for the replies; your explanation/examples helped solve the
problem I had been stuck!

Many thanks!

Regards,

Bilal B.


*** Sent via Developersdex http://www.developersdex.com ***
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ASP.NET 2.0 Impersonation of fixed identity - truncation of identity JimLad ASP .Net 0 01-16-2009 10:42 AM
HttpContext.Current.User.Identity.Name AND Context.User.Identity.Name; nalbayo ASP .Net 2 11-11-2005 11:12 PM
Issue with Identity Impersonation and user identity used passed for trusted SQL connection. Frederick D'hont ASP .Net Security 0 07-25-2005 02:41 PM
how to get the identity transformation to stop outputting extra 'xmlns:' attrib ? _clb_ Chris Bedford XML 1 05-21-2004 07:27 AM
Difference between HttpContext.Current.User.Identity and identity Impersonation Giovanni Bassi ASP .Net 0 10-20-2003 02:25 PM



Advertisments