[Home] [By Thread] [By Date] [Recent Entries]
At 2009-04-12 21:07 +0200, fred@xxxxxxxxxxxxx wrote:
I am using XSLT to walk through an XML Schema to construct an Xforms (output) instance. In parallel I am scanning an (input) instance (of a document defined by the schema) to include default values in the form. I'm assuming the structures of the two documents are identical. Scanning of the input instance is done by means of a variable that keeps track of the path. The variable is updated (renewed) each time a template is (recursively) called with the variable as parameter: Correct, because there is no such thing as "eval()" in XPath. The final step of your XPath address is the value of a variable, so you are getting the value of the variable as you should. And who is to say that your prefixes in your input document match the prefixes in your default value document? I would expect you to see the string "rsm:DeliveryDate", not nothing.
You could use a key table, where the lookup value for each element is that element's fully-qualified XPath address. And you could use the "{namespace-uri}local-name" syntax for each element in the path in order to be independent of namespace prefixes. Then you use: <xsl:value-of select="document('file:/C:/dir/order.xml')/
key('myTable',$instance.path))"/>and it will return the value of the element. You don't give any sample data to test with, and you don't talk about sibling elements of the same name, but I think this approach would work for you. An example is below where each element of fred.xml is replaced with the corresponding value from fred-default.xml. I hope this helps. . . . . . . . . . . . . . Ken
<xsl:key name="paths" match="*" use="f:make-path(.)"/> <!--walk the element tree-->
<xsl:template match="*">
<xsl:param name="path"/>
<!--determine the path to this element-->
<xsl:variable name="this-path"
select="concat($path,f:make-step(.))"/>
<!--preserve the element structure-->
<xsl:copy>
<!--preserve any attributes-->
<xsl:apply-templates select="@*"/>
<!--replace the value when there are no element children-->
<xsl:choose>
<xsl:when test="not(*)">
<!--at a leaf element-->
<xsl:value-of select="document('fred-default.xml')/
key('paths',$this-path)"/>
</xsl:when>
<xsl:otherwise>
<!--at a branch element, keep going-->
<xsl:apply-templates>
<xsl:with-param name="path" select="$this-path"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template><!--identity for all other nodes--> <xsl:template match="@*|comment()|processing-instruction()"> <xsl:copy/> </xsl:template> <!--create a lookup key-->
<xsl:function name="f:make-path">
<xsl:param name="element"/>
<xsl:sequence select="string-join( for $e in $element/ancestor-or-self::*
return f:make-step( $e ), '' )"/>
</xsl:function><xsl:function name="f:make-step">
<xsl:param name="element"/>
<xsl:for-each select="$element">
<xsl:sequence select="concat('/{',namespace-uri(.),'}',local-name(.),
'[',count(preceding-sibling::*[node-name(.)=node-name(current())])+1,
']')"/>
</xsl:for-each>
</xsl:function></xsl:stylesheet> T:\ftemp>rem Done! -- XSLT/XSL-FO/XQuery training in Los Angeles (New dates!) 2009-06-08 Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video Video lesson: http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18 Video overview: http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18 G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc Legal business disclaimers: http://www.CraneSoftwrights.com/legal
|

Cart



