[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: [xsl] Namespaces, params and Xalan


Subject: RE: [xsl] Namespaces, params and Xalan
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Fri, 24 Sep 2004 08:25:14 +0100

First, what is this?:

node()[(../. = /) and not(self::cmn:Comments)]

../. means the same as .., so you are trying to match any node whose parent
has a string-value that is the same as the string-value of the root node.
Getting the string-value of the root node is a pretty expensive operation,
it involves scanning the whole document. I suspect you are trying to match
the element whose parent is the root node, in which case you can write
match="/*". And the not(self::xxx) part is much better handled by defining a
second template rule with higher priority that has match="cmn:Comments". 

Secondly, in the JAXP code you are frequently using Windows filenames in
places where URIs are expected. Xalan may let you get away with this (I
don't know) but Saxon certainly won't.

Thirdly, this expression: [name()=name(current())] is pretty fragile in an
environment with so many namespaces, because you are comparing prefixes, not
URIs. Test whether the namespace-uri and local-name are both equal.

Fourthly, you don't need xalan-nodeset(). The input is already a node-set,
you don't need to convert it.

Finally, for debugging try simply doing <xsl:copy-of> on the supplied
parameter in your match="/" template. Displaying the result of your complex
path expression simply proves that your path expression is wrong.

Michael Kay



> -----Original Message-----
> From: Fraser Crichton [mailto:fraser.crichton@xxxxxxxxxxxxxxxxxxxxx] 
> Sent: 24 September 2004 03:05
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Namespaces, params and Xalan
> 
>   Hi,
> 
> I'm a bit stumped by this - I'm using Xalan and trying to pass an xml 
> fragment into my xsl as a parameter and then merge the 
> fragment with my 
> instance document.
> 
> What seems to happen is that the namespaces get stripped and I can't 
> query the XML fragment once it's passed in as a param e.g 
> xalan:nodeset($override)/cmn:MinorVersion/cmn:Number won't return 
> anything from the fragment because the fully qualified name 
> in the xpath 
> query isn't in the fragment (I can however use local-name() to return 
> something but that's a bit of a hack).
> 
> I saw something recently from Jenni Tennison that suggested that -
> 
>        transformer.setParameter("TEXT", node);
> 
> effectively passes the node as a string and that this could 
> cause problems?
> 
> Or is it just something stupid I'm missing?
> 
> I'm also looking at trying to get saxon to do the same thing 
> with some 
> problems.
> 
> Any help would be most welcome.
> 
> My fragment looks like this -
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <AccreditationModerationActionPlan
> xmlns:cmn="http://www.nzqa.govt.nz/namespace/eqa/qual/commonV0"
> xmlns:cfn="http://www.nzqa.govt.nz/namespace/eqa/qual/classifi
> cationV0"
> xmlns:std="http://www.nzqa.govt.nz/namespace/eqa/qual/standardV0"
> xmlns="http://www.nzqa.govt.nz/namespace/eqa/qual/accreditatio
> nModerationActionPlanV0">
>   <cmn:Creator>Andy Mark Martin</cmn:Creator>
>   <cmn:GenerationDate>22 Sep 2004</cmn:GenerationDate>
>   <cmn:Item>
>     <cmn:Number>9999</cmn:Number>
>     <cmn:Status>99</cmn:Status>
>   </cmn:Item>
>   <cmn:Version>
>     <cmn:Number>01</cmn:Number>
>     <cmn:Status>01a</cmn:Status>
>   </cmn:Version>
>   <cmn:MinorVersion>
>     <cmn:Number>777777</cmn:Number>
>     <cmn:Status>02b</cmn:Status>
>   </cmn:MinorVersion>
>   <cmn:ClientId>0</cmn:ClientId>
>   <cmn:StandardsSettingBody>
>     <cmn:Reference>An ssbRef</cmn:Reference>
>     <cmn:Name>Laura Martin</cmn:Name>
>     <cmn:Number>2</cmn:Number>
>   </cmn:StandardsSettingBody>
>   <Title>A Title</Title>
>   <Scope/>
> </AccreditationModerationActionPlan>
> 
> The transformation code looks like this -
> 
> 
>       // We now have a juicy chunk of xml that we want to 
> merge into the 
> xml document.
>       TransformerFactory transformerFactory = 
> TransformerFactory.newInstance();
>      
>       String stylesheet = 
> "C:/work/eQA/qual/src/xml/xslt/databaseMergeV0.xsl";
>       Transformer transformer = transformerFactory.newTransformer(new 
> StreamSource(stylesheet));
> 
>       DocumentBuilderFactory dbF = 
> DocumentBuilderFactory.newInstance();
>       
>        //Now I can use the namespaces in the DOM node
>       dbF.setNamespaceAware(true);
> 
>       DocumentBuilder db = dbF.newDocumentBuilder();
>       File fragment = new 
> File("C:/work/eQA/qual/src/xml/Examples/test-cases/fragment.xml");
> 
>       Document doc = db.parse(fragment);
> 
>       NodeList nodes = doc.getChildNodes();
> 
>       FileWriter fileWriter = new FileWriter("c:/temp/xalanTest.xml");
>       FileReader fileReader = new 
> FileReader("C:/work/eQA/qual/src/xml/Examples/test-cases/amapD
> raft.xml");
>       transformer.clearParameters();
>       transformer.setParameter("override", nodes.item(0));
>       transformer.transform(new StreamSource(fileReader), new 
> StreamResult(fileWriter));
>       fileWriter.flush();
> 
> My XSL looks like this -
> 
> <?xml version="1.0" encoding="UTF-8"?>
> <xsl:stylesheet
>      
> xmlns="http://www.nzqa.govt.nz/namespace/eqa/qual/accreditatio
> nModerationActionPlanV0"
>     xmlns:a="urn:oasis:names:tc:ciq:xsdschema:xAL:2.0"
>     
> xmlns:amap="http://www.nzqa.govt.nz/namespace/eqa/qual/accredi
> tationModerationActionPlanV0" 
> 
>      
> xmlns:as="http://www.nzqa.govt.nz/namespace/eqa/qual/achieveme
> ntStandardV0"
>     
> xmlns:anta="http://www.nzqa.govt.nz/namespace/eqa/qual/austral
> ianNationalTrainingAuthorityStandardV0" 
> 
>     
> xmlns:cfn="http://www.nzqa.govt.nz/namespace/eqa/qual/classifi
> cationV0"
>     xmlns:cmn="http://www.nzqa.govt.nz/namespace/eqa/qual/commonV0"
>   xmlns:doc="http://www.nzqa.govt.nz/xsl/documentation/1.0"
>   xmlns:i="urn:oasis:names:tc:ciq:xsdschema:xCIL:2.0"
>     
> xmlns:mas="http://www.nzqa.govt.nz/namespace/eqa/qual/mathAchi
> evementStandardV0"
>     xmlns:n="urn:oasis:names:tc:ciq:xsdschema:xNL:2.0"
>     xmlns:r="urn:oasis:names:tc:ciq:xsdschema:xCRL:2.0"
>     xmlns:std="http://www.nzqa.govt.nz/namespace/eqa/qual/standardV0"
>     xmlns:txt="http://www.nzqa.govt.nz/namespace/eqa/qual/textV0"
>      
> xmlns:us="http://www.nzqa.govt.nz/namespace/eqa/qual/unitStandardV0"
>     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
>     xmlns:xalan="http://xml.apache.org/xalan"
>     exclude-result-prefixes="a amap as anta cfn cmn doc i mas n r std 
> txt us xsi xalan"
>     version="1.0">
> 
>     <!-- Common copying templates -->
>      <xsl:import href="copyV0.xsl"/>
>   
>   <xsl:param name="override" />
> 
> 
> <!--                                                        NAMED 
> TEMPLATES                                                     -->
> 
>     <xsl:template name="debug">
>         <xsl:comment>Dynamically generated data</xsl:comment>
>         <xsl:message>
>             <xsl:text>Dynamically generating element named - 
> {</xsl:text>
>             <xsl:value-of select="namespace-uri()"/>
>             <xsl:text>} </xsl:text>
>             <xsl:value-of select="name()"/>
>         </xsl:message>
>     </xsl:template>
> 
> <!--                                                        MATCHED 
> TEMPLATES                                                     -->
> 
>     <xsl:template match="/">
>    
>         <xsl:apply-templates />
>     </xsl:template>
> 
>     <xsl:template match="node()[(../. = /) and 
> not(self::cmn:Comments)]">
> 
>         <!-- Query $override as a node-set to see if the 
> current element 
> also exists
>         in the database generated fragement that has been 
> passed in as a 
> parameter-->
>         <xsl:variable name="fragment" 
> select="xalan:nodeset($override)/node()/node()[name()=name(cur
> rent())]"/>
> 
>         <xsl:choose>
>             <xsl:when test="$fragment">
>                 <xsl:call-template name="debug" />
>                 <xsl:message>
>                     **{<xsl:value-of 
> select="namespace-uri($fragment)"/>}<xsl:value-of 
> select="name($fragment)"/>
>                 </xsl:message>
>         <xsl:copy-of select="$fragment" />
>             </xsl:when>
>             <xsl:otherwise>
>             <xsl:copy><xsl:apply-templates 
> select="@*|node()"/></xsl:copy>
>             </xsl:otherwise>
>         </xsl:choose>
>     </xsl:template>
> 
>     <xsl:template match="cmn:Comments">
> 
>         <xsl:variable name="fragmentMinorVersionNumber" 
> select="xalan:nodeset($override)/node()[./node()]/node()[local
> -name() = 
> 'MinorVersion']/node()[local-name()='Number']" />
> 
>         <xsl:copy>
>             <xsl:if test="not(cmn:Comment[@MinorVersionNumber = 
> $fragmentMinorVersionNumber])">
>                 <xsl:call-template name="debug" />
>                 <xsl:message>
>                  comment frag <xsl:value-of 
> select="$fragmentMinorVersionNumber"/>
>                 </xsl:message>
>                 <cmn:Comment 
> MinorVersionNumber="{$fragmentMinorVersionNumber}" />
>             </xsl:if>
>             <xsl:apply-templates select="@*|cmn:Comment">
>                 <xsl:sort order="descending" 
> select="@MinorVersionNumber" />
>             </xsl:apply-templates>
>         </xsl:copy>
>     </xsl:template>
>    
> 
> </xsl:stylesheet>
> 
> 
> 
> -- 
> Fraser Crichton
> Web Developer
> SolNet Solutions Limited
> L12, SolNet House, 70 The Terrace
> PO Box 397, Wellington, Aotearoa / New Zealand
> www.solnetsolutions.co.nz <http://www.solnetsolutions.co.nz>
> DDI: 04-462-5078
> Mob: 027-278-3392
> Fax: 04-462-5011
> email: fraser.crichton@xxxxxxxxxxxxxxxxxxxxx 
> <mailto:fraser.crichton@xxxxxxxxxxxxxxxxxxxxx>
> -- 
> Fraser Crichton
> Web Developer
> SolNet Solutions Limited
> L12, SolNet House, 70 The Terrace
> PO Box 397, Wellington, Aotearoa / New Zealand
> www.solnetsolutions.co.nz <http://www.solnetsolutions.co.nz>
> DDI: 04-462-5078
> Mob: 027-278-3392
> Fax: 04-462-5011
> email: fraser.crichton@xxxxxxxxxxxxxxxxxxxxx 
> <mailto:fraser.crichton@xxxxxxxxxxxxxxxxxxxxx>
> 
> Attention:
> This email may contain information intended for the sole use of
> the original recipient. Please respect this when sharing or
> disclosing this email's contents with any third party. If you
> believe you have received this email in error, please delete it
> and notify the sender or postmaster@xxxxxxxxxxxxxxxxxxxxx as
> soon as possible. The content of this email does not necessarily
> reflect the views of SolNet Solutions Ltd.


Current Thread
Keywords