 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

February 16th, 2009, 08:03 AM
|
|
Friend of Wrox
|
|
Join Date: Jan 2006
Posts: 131
Thanks: 10
Thanked 0 Times in 0 Posts
|
|
xmlns as an attribute
xslt version 1.0
Hi,
I know that there is a problem when defining 'xmlns' as an attribute. But is there a work-around?
Here is my code example...
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:md="http://schemas.microsoft.com/dynamics/2006/02/documents/VCTMovementDelivery" xmlns:js-function="//CALjs-functions">
<!-- Import the CAL js-functions template -->
<xsl:import href="CALjs-functions.xslt"/>
<xsl:variable name="strDlvMode" select="./Envelope/Body/md:VCTMovementDelivery/md:VCTMovements//md:DivMode[position()=1]"/>
<xsl:variable name="strDestEndPnt" select="./Envelope/Header/DestinationEndPoint"/>
<xsl:variable name="strDocPurpose" select="./Envelope/Body/md:VCTMovementDelivery/md:DocPurpose"/>
<xsl:variable name="strVCTActDlyDte" select="./Envelope/Body/md:VCTMovementDelivery/md:VCTMovements//md:VCTActualDeliveryDate[position()=1]"/>
<xsl:variable name="strVCTMoveID" select="count(./Envelope/Body/md:VCTMovementDelivery/md:VCTMovements//md:VCTMovementId)"/>
<xsl:variable name="lenDlvMode" select="string-length($strDlvMode)"/>
<xsl:variable name="lenVCTActDlyDte" select="string-length($strVCTActDlyDte)"/>
<xsl:variable name="lenVCTMoveID" select="string-length($strVCTMoveID)"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="/">
<xsl:call-template name="F4FDelvyNotif"/>
</xsl:template>
<xsl:template name="F4FDelvyNotif">
<xsl:element name="F4FDeliveryNotification">
<xsl:attribute name="xmlns:xsi">http://www.w3.org/2001/XMLSchema-instance</xsl:attribute>
<xsl:attribute name="xsi:noNamespaceSchemaLocation">http://www.first4farming.com/F4FXML/Schemas/v3_0_3/F4FDel.xsd</xsl:attribute>
<xsl:attribute name="DeliveryNotificationType">
<xsl:choose>
<xsl:when test="$strDestEndPnt='F4FGRNMovementDeliveryNote'">
<xsl:text>Goods Received Note</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text></xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="DocumentType">
<xsl:choose>
<xsl:when test="$strDocPurpose='Original'">
<xsl:text>New</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text></xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:call-template name="DocHdr"/>
<xsl:call-template name="DlyNotHdr"/>
<xsl:call-template name="TrnsDtls"/>
<xsl:call-template name="DlyLine"/>
<xsl:call-template name="DlyCtrlTtls"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Can anyone help please?
Thanks in advance,
__________________
Neal
A Northern Soul
|
|

February 16th, 2009, 08:11 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
In the XSLT/XPath data model namespace declarations are not attributes but rather namespace nodes.
As for your code, if you want to create result elements then simply use literal result elements e.g.
Code:
<xsl:template name="F4FDelvyNotif">
<F4FDeliveryNotification xmlns:xsi="http:/www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.first4farming.com/F4FXML/Schemas/v3_0_3/F4FDel.xsd">
and use xsl:attribute only when you want to compute the attribute name and/or value.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|
The Following User Says Thank You to Martin Honnen For This Useful Post:
|
Neal (February 16th, 2009)
|
|

February 16th, 2009, 08:23 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
If you use a namespace in the name of a constructed element or attribute, the namespace will automatically be declared in the result document - you don't need to worry about it.
The only time you need to worry about creating a namespace node is in the rare case where you want to declare a namespace without using it in the name of an element or attribute. For this situation, XSLT 2.0 provides the xsl:namespace instruction.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

February 16th, 2009, 08:38 AM
|
|
Friend of Wrox
|
|
Join Date: Jan 2006
Posts: 131
Thanks: 10
Thanked 0 Times in 0 Posts
|
|
Thanks,
Believe it or not, I did try this earlier. However, the problem is that it appears all of my subsquent code (I only displayed a small section above) now needs to change.
For example, once I add the suggested (above) code, I get the following message:
Required attribute 'DeliveryNotificationType' of parent element 'F4FDeliveryNotification' expexted before first child element.
i.e. When atempting to validate/transform the next line:
Code:
<xsl:attribute name="DeliveryNotificationType">
XLST expects '<DeliveryNotificationType>' NOT ' attribute'.
__________________
Neal
A Northern Soul
|
|

February 16th, 2009, 08:51 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
Show us how you made the change, and we can tell you how you got it wrong.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|

February 16th, 2009, 10:27 AM
|
|
Friend of Wrox
|
|
Join Date: Jan 2006
Posts: 131
Thanks: 10
Thanked 0 Times in 0 Posts
|
|
Ok, so I've amended my code to include the suggested line from Martin...
Notice that I've altered the <F4FDeliveryNotification> line to include the ' DeliveryNoficiationType' and ' DocumentType' attributes (This isn't ideal as both attribute values are based on conditions (see 1st post)).
The problem is that XMLSpy now states that the 'Mandatory element ' F4FDocumentHeader' expected in place of 'xsl:call-template'.
NOTE
' F4FDocumentHeader'' appears in the DocHdr template
Code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:md="http://schemas.microsoft.com/dynamics/2006/02/documents/VCTMovementDelivery" xmlns:js-function="//CALjs-functions">
<!-- Import the CAL js-functions template -->
<xsl:import href="CALjs-functions.xslt"/>
<xsl:variable name="strDlvMode" select="./Envelope/Body/md:VCTMovementDelivery/md:VCTMovements//md:DivMode[position()=1]"/>
<xsl:variable name="strDestEndPnt" select="./Envelope/Header/DestinationEndPoint"/>
<xsl:variable name="strDocPurpose" select="./Envelope/Body/md:VCTMovementDelivery/md:DocPurpose"/>
<xsl:variable name="strVCTActDlyDte" select="./Envelope/Body/md:VCTMovementDelivery/md:VCTMovements//md:VCTActualDeliveryDate[position()=1]"/>
<xsl:variable name="strVCTMoveID" select="count(./Envelope/Body/md:VCTMovementDelivery/md:VCTMovements//md:VCTMovementId)"/>
<xsl:variable name="lenDlvMode" select="string-length($strDlvMode)"/>
<xsl:variable name="lenVCTActDlyDte" select="string-length($strVCTActDlyDte)"/>
<xsl:variable name="lenVCTMoveID" select="string-length($strVCTMoveID)"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="/">
<xsl:call-template name="F4FDelvyNotif"/>
</xsl:template>
<xsl:template name="F4FDelvyNotif">
<F4FDeliveryNotification xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.first4farming.com/F4FXML/Schemas/v3_0_3/F4FDel.xsd" DeliveryNotificationType="Goods Received Note" DocumentType="New">
<xsl:call-template name="DocHdr"/>
<!--<xsl:call-template name="DlyNotHdr"/>
<xsl:call-template name="TrnsDtls"/>
<xsl:call-template name="DlyLine"/>
<xsl:call-template name="DlyCtrlTtls"/>-->
</F4FDeliveryNotification>
</xsl:template>
<xsl:template name="DocHdr">
<xsl:element name="F4FDocumentHeader">
<xsl:element name="SchemaVersion">
<xsl:text>3</xsl:text>
</xsl:element>
<xsl:element name="SchemaStatus">
<xsl:text>Approved</xsl:text>
</xsl:element>
<xsl:element name="DocumentCreated">
<xsl:attribute name="DateTimeType">Document Created</xsl:attribute>
<!--<xsl:value-of select="js-function:DateTimeNow()"/>-->
<!--<xsl:value-of select="js-function:DateTimeNow()"></xsl:value-of>-->
<xsl:text>TBA</xsl:text>
</xsl:element>
<xsl:element name="DocumentTrackingId">
<xsl:value-of select="concat(./Envelope/Header/SourceEndpoint,'GRN',./Envelope/Body/md:VCTMovementDelivery/md:VCTMovements/md:VCTMovementId[position()=1])"/>
</xsl:element>
<xsl:element name="DocumentRevisionNumber">
<xsl:text>1</xsl:text>
</xsl:element>
<xsl:element name="SourcePartnerId">
<xsl:value-of select="./Envelope/Header/SourcePartnerId"/>
</xsl:element>
<xsl:element name="SourceDivisionId">
<xsl:value-of select="./Envelope/Header/SourceDivisionId"/>
</xsl:element>
<xsl:element name="DestinationPartnerId">
<xsl:value-of select="./Envelope/Header/DestinationPartnerId"/>
</xsl:element>
<xsl:element name="DestinationDivisionId">
<xsl:value-of select="./Envelope/Header/DestinationDivisionId"/>
</xsl:element>
</xsl:element>
</xsl:template>
<xsl:template name="copy">
<xsl:copy>
<xsl:for-each select="@*">
<xsl:copy/>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
HTH
__________________
Neal
A Northern Soul
|
|

February 16th, 2009, 10:35 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
I wouldn't worry about validation messages inside of an XSLT stylesheet. In the result document the validation is meaningful but inside of an XSLT stylesheet template where you mix XSLT instructions and result elements I wouldn't worry about an XML editor complaining, it is simply confused by the xsi:noNamespaceSchemaLocation.
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

February 16th, 2009, 10:38 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
You'll have to check this with Altova, but my recollection is that when they see an xsi:schemaLocation attribute anywhere in an XML document, they immediately apply schema processing to the containing element. The schema doesn't allow a F4FDeliveryNotification element to contain an xsl:call-template element, so they are rejecting it as invalid.
Personally, I think that's a pretty crass piece of design, but you can work around it by using <xsl:attribute> (as you were doing originally) or by declaring a namespace alias for the xsi namespace.
__________________
Michael Kay
http://www.saxonica.com/
Author, XSLT 2.0 and XPath 2.0 Programmer\'s Reference
|
|
 |