xml - Use One Template for Attribute (by Value) and Another for the (Parent) Node -


i getting ambiguous match warning on largish (420 lines) xsl transformation of large (tei-flavored) xml file (~6000 lines) (using saxon-he 9.5.1.6j on os x). i'd understand (and fix) warning.

 recoverable error    xtre0540: ambiguous rule match /tei/text[1]/group[1]/text[1]/body[1]/lg[33]/head[2]  matches both "tei:lg[@type='poem']/tei:head" on line 103 of   file: hs2latex.xsl  , "*[@rend='italics']" on line 110 of   file: hs2latex.xsl 

the xml looks like:

<lg type='poem'> <head rend='italics'>sonnet 3<head> ... </lg> 

with conflicting xsl rules looking this:

<xsl:template match="tei:lg[@type='poem']/tei:head"> ... <xsl:apply-templates /> </xsl:template> 

and

<xsl:template match="*[@rend='italics']"><!-- blah blah --></xsl:template> 

since attribute node, thought match against separately. if have just attribute in match, error, put used asterisk match nodes rend='italics' attributes, produces ambiguous error quoted above.

is possible trying here, namely use 1 template match attributes based on value (regardless of type of element)? interested in having single template handle element with, instance, "@rend='italics'" attribute.

i tried reproduce problem minimal working example, came different example (which perhaps go i'm misunderstanding).

minimal working xml

<?xml version="1.0" encoding="utf-8"?>  <document>   <book>     <title>"one title"</title>   </book>    <book>     <title rend="italics">another title</title>   </book> </document> 

and minimal xslt

<?xml version="1.0" encoding="utf-8"?>  <xsl:stylesheet version="2.0"          xmlns:xsl="http://www.w3.org/1999/xsl/transform"          exclude-result-prefixes="xsl">   <xsl:output omit-xml-declaration="yes" />   <xsl:template match="/">     <xsl:apply-templates />   </xsl:template>    <xsl:template match="*[@rend='italics']">     <italics><xsl:apply-templates /></italics>   </xsl:template>    <xsl:template match="title">     <title><xsl:apply-templates /></title>   </xsl:template>  </xsl:stylesheet> 

this minimal example (which thought produces identical situation 1 describe above) not produce ambiguous match error, instead results in output:

<title>"one title"</title> <italics>another title</italics> 

what wanted (in minimal example) be:

<title>"one title"</title> <title><italics>another title</italics></title> 

i suspect misunderstanding basic xslt or xpath, @ point @ loss , appreciate guidance. many thanks.

is possible trying here, namely use 1 template match attributes based on value (regardless of type of element)? interested in having single template handle element with, instance, "@rend='italics'" attribute.

yes, possible. problem in code have 2 matching templates of form nodetest[predicate], both take same priority default. if want 1 take precedence on other, should add priority="x" , x number. i.e.:

<xsl:template match="*[@rend='italics']" priority="2">   <italics><xsl:apply-templates /></italics> </xsl:template> 

this minimal example (which thought produces identical situation 1 describe above) not produce ambiguous match error, instead results in output:

correct. because in xslt, default values assigned priorities based on complexity of match pattern. nodetest has lower precedence nodetest[predicate].

since attribute node, thought match against separately.

yes, can. didn't show tried attribute matching, should this: match="@rend" or match="@rend[. = 'italics']". however, aware attributes special nodes. need apply templates attributes able match them. also, node has focus attribute node itself, may have walk parent axis same results having.

what wanted (in minimal example) be:

what seem want when more generic match matches, want specific match applied same node. node matches @ one matching template. have 1 node match multiple templates, can use xsl:next-match instruction. however, works specific (which matched first) generic (which matched last).

in case, want reverse. this, gives output expect (all title-elements match title template first, because of explicit priority, , italics elements match italics template, adding <italics> output):

<xsl:template match="/">     <xsl:apply-templates /> </xsl:template>  <xsl:template match="*[@rend='italics']">     <italics><xsl:apply-templates /></italics> </xsl:template>  <xsl:template match="title" priority="2">     <title><xsl:next-match /></title> </xsl:template> 

you may want apply similar coding pattern larger example, otherwise, <italics> 1 matched, , think want both match there well, , in right order (generic first, specific).


Comments

Popular posts from this blog

javascript - Jquery show_hide, what to add in order to make the page scroll to the bottom of the hidden field once button is clicked -

javascript - Highcharts multi-color line -

javascript - Enter key does not work in search box -