Reputation: 412
I need to calculate a few values and store them in a variable. I pass a document node into xsl:apply-templates
and specify the mode:
<xsl:variable as="xs:string*" name="checkAccidentalsVisibility">
<xsl:apply-templates mode="checkAccidentalsVisibility" select="$extractMainVersion"/>
</xsl:variable>
But the template for this mode does not match:
<xsl:template match="body//@accid[not(parent::accid/@func[. = 'caution'] or ancestor::note[@grace])]" mode="checkAccidentalsVisibility" >...
The identity transform template is specified like this, bcs I don't need to copy the xml tree.
<xsl:template match="node() | @*" mode="extractMainVersion changeAccid">
<xsl:copy>
<xsl:apply-templates mode="#current" select="node() | @*"/>
</xsl:copy>
</xsl:template>
The value of $checkAccidentalsVisibility is the text node. For instance, applied on this XML I get an example:
<?xml version="1.0" encoding="UTF-8"?>
<mei meiversion="3.0.0" xml:id="dme92517025-f4c2-4231-a1c3-b70f02802d61" xmlns="http://www.music-encoding.org/ns/mei">
<meiHead meiversion="3.0.0">
<fileDesc>
<titleStmt>
<title label="NMA digital" type="unit">an example</title>
</titleStmt>
<pubStmt/>
</fileDesc>
</meiHead>
<music meiversion="3.0.0">
<body>
<mdiv n="2a" xml:id="mdiv_">
<score xml:id="score_">
<section label="menuetto_A" xml:id="section_A_m1-5">
<measure n="1" xml:id="m1_k_">
<staff n="1" xml:id="staff_108">
<layer n="1" xml:id="layer_114">
<note accid.ges="f" dur="2" oct="4" pname="e" tstamp="1" xml:id="note_120"/>
<choice xml:id="choice_132">
<sic xml:id="corr_132">
<note dur="4" oct="4" pname="e" tstamp="3" xml:id="note_132">
<accid accid="f" xml:id="accid_138"/>
</note>
</sic>
<orig xml:id="orig_132">
<note dur="4" oct="4" pname="e" tstamp="3" xml:id="note_132b">
<accid accid="f" xml:id="accid_138b"/>
</note>
</orig>
</choice>
</layer>
</staff>
</measure>
</section>
</score>
</mdiv>
</body>
</music>
</mei>
I am expecting a sequence of @xml:id-values which I derive from my calculations.
Upvotes: 0
Views: 288
Reputation: 340
As Michael Kay pointed out it's the missing override for the default attribute template, the latter being something like:
<xsl:template match="@*">
<xsl:value-of select="."/>
</xsl:template>
So you should add something similar to:
<xsl:template match="node()|@*" mode="checkAccidentalsVisibility">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
Upvotes: 1
Reputation: 412
The whole xslt is quite large and modularized. I do not know how is it possible to post here all the content... E.g. this is the main stylesheet:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet exclude-result-prefixes="xs xd mei dme map" version="3.0" xmlns:dme="http://www.mozarteum.at/ns/dme" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:mei="http://www.music-encoding.org/ns/mei" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.music-encoding.org/ns/mei">
<xsl:include href="modules/basic.xsl"/>
<xsl:include href="modules/extractMainVersion.xsl"/>
<xsl:include href="modules/check_contextNote.xsl"/>
<xsl:include href="modules/changeAccid.xsl"/>
<xsl:variable as="xs:string*" name="checkAccidentalsVisibility">
<xsl:variable name="extractMainVersion">
<xsl:apply-templates mode="extractMainVersion" select="."/>
</xsl:variable>
<xsl:apply-templates mode="checkAccidentalsVisibility" select="$extractMainVersion//@accid"/>
</xsl:variable>
<xd:doc>
<xd:desc/>
</xd:doc>
<xsl:template match="/">
<xsl:apply-templates mode="changeAccid" select="."/>
</xsl:template>
</xsl:stylesheet>
The template
<xsl:template match="body//@accid[not(parent::accid/@func[. = 'caution'] or ancestor::note[@grace])]" mode="checkAccidentalsVisibility" >...
is placed in check_contextNote.xsl
. And this is the only template with the mode checkAccidentalsVisibility but it calls plenty of other templates and functions later.
Originally, I didn't have the $checkAccidentalsVisibility and did not need to have various modes and the template was matched well. Later, I needed to change the program logic and separate the following:
So I added three modes. Two of them I added to the identity transform template (originally, it was set to #all
). This is basic.xsl:
<xsl:stylesheet exclude-result-prefixes="xs xd mei dme map" version="3.0" xmlns:dme="http://www.mozarteum.at/ns/dme" xmlns:map="http://www.w3.org/2005/xpath-functions/map" xmlns:mei="http://www.music-encoding.org/ns/mei" xmlns:xd="http://www.oxygenxml.com/ns/doc/xsl" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.music-encoding.org/ns/mei">
<xsl:output encoding="UTF-8" indent="yes" method="xml"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node() | @*" mode="extractMainVersion changeAccid">
<xsl:copy>
<xsl:apply-templates mode="#current" select="node() | @*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0
Reputation: 163458
As far as I can tell from the code fragments supplied, you have not defined any "fallback" template for the mode checkAccidentalsVisibility
, therefore when you apply-templates to a document node in this mode, the built-in template rules kick in, and the default rule for elements uses apply-templates to process the children of the element but not its attributes. So attributes don't get processed.
Upvotes: 1
Reputation: 412
When explicitly passing the attributes to the @select
they are matched. So,:
<xsl:apply-templates mode="checkAccidentalsVisibility" select="$extractMainVersion//@accid"/>
matches here:
<xsl:template match="body//@accid[not(parent::accid/@func[. = 'caution'] or ancestor::note[@grace])]" mode="checkAccidentalsVisibility">
@Martin Honnen: $extractMainversion
contains a document-node with the value <#documentfragment>
which is almost the same as the XML snippet above.
The $checkAccidentalsVisibility
was previously containing a string derived from //title/text()
Probably I didn't describe it well.
Although I solved the problem, I'd be interested, why you cannot match the @attributes in the way as you would normally do it without modes?
Upvotes: 0