Re: [xsl] Question about isolating records

Subject: Re: [xsl] Question about isolating records
From: "Mark Wilson pubs@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Sun, 6 Sep 2015 06:13:44 -0000
Ken,
In my original question, when @crawford-number from File1 matched <Shelfmark> in FILE2, I wanted the contents of <PDF> from File2 as the value of pdf-number in File1. (An entire <Item> from File2 is reproduced after the stylesheet below, if needed.)


I returned to my original structure as the code you provided failed to reproduce the <Tag> value.

Inserting substring-before(key(...), 'Crawford') worked on my test file of one record, but when I presented the complete file, Saxon complained that the first argument of substring-before() can not be a sequence. I tried putting the key() in a variable and calling substring-before() on the variable, but got the same complaint.

What is being returned when I run the full file of multiple records is:

(with <xsl:strip-space elements="*"/>)
pdf-number="016677041Crawford 2212.The Journal of the Philatelic Literature Society.">852</Tag>
pdf-number="016677042Crawford 2215.Le Magasin pittoresque,">852</Tag>


(without <xsl:strip-space elements="*"/>)
pdf-number="&#xA; 016677041&#xA; Crawford 2212.&#xA; The Journal of the Philatelic Literature Society.&#xA; ">852</Tag>
pdf-number="&#xA; 016677042&#xA; Crawford 2215.&#xA; Le Magasin pittoresque,&#xA; ">852</Tag>



The PDF numbers, from FILE2's <PDF> are 016677041 and 016677042. All <PDF> numbers contain the same number of digits, if that helps, and are always the first piece of data in the return from key().


That is, the key() is finding the right <Item> in FILE2 (single-crawford-docs.xml), but is returning the entire contents of that <Item>. How can it be limited to <PDF>? I cannot understand where I tell the stylesheet I am only interested in the contents of <PDF>. Here is the entire stylesheet which I think reproduces your code with the exception that the <Tag> data is hard coded.

 <xsl:output method="xml"/>
    <xsl:strip-space elements="*"/>

    <xsl:key name="pdf-key" match="Item" use="Shelfmark"/>
    <xsl:template match="@* | node()">
        <xsl:copy copy-namespaces="no">
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

<xsl:template match="Tag">
<xsl:choose>
<xsl:when test=". eq '852'">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:for-each select="@crawford-number">
<xsl:attribute name="pdf-number" select="key('pdf-key', ., doc('single-crawford-docs.xml'))"/>
<xsl:value-of select="'852'"/>
</xsl:for-each>
</xsl:copy>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>


    </xsl:template>
----------------
FILE2:
<List>
    <Item>
        <PDF>016678286</PDF>
        <Shelfmark>Crawford 2411.</Shelfmark>
        <Title>General-Anzeiger f|r Philatelie.</Title>
    </Item>
</List>



On 9/5/2015 8:49 PM, Mark Wilson pubs@xxxxxxxxxxxx wrote:
Thank you,

I got to work with one small change to your suggested code:

<xsl:attribute name="pdf-number" select="substring-before(key('pdf-key', ., doc('test-xml.xml')), 'Crawford')"/>

My major misunderstanding was of the <xsl:key/> statement, not realizing that is was not a 'variable to be loaded when called' and that the key() function later would parse the data in FILE2.

Also, thanks for reopening the book for me.
Regards,
Mark

On 9/5/2015 7:20 PM, G. Ken Holman g.ken.holman@xxxxxxxxx wrote:
At 2015-09-05 23:46 +0000, Mark Wilson pubs@xxxxxxxxxxxx wrote:
I am still missing something -- I have been building the key in File 1 with this code:
<xsl:key name="pdf-key" match="Item" use="doc('FILE2')//Shelfmark"/>

You've transcribed my suggestion incorrectly. The use= attribute is relative to the match= node. I expressly used use="Shelfmark". The File2 tree is accessed when you use the third argument to the key() function.


That, of course, gives me all the content of every <Items> as my pdf-number when I call
<xsl:attribute name="pdf-number" select="key('pdf-key', ., doc('test-xml.xml'))"/>

Right ... because you didn't use the code I gave you.


If I use:
<xsl:key name="pdf-key" match="Item" use="doc('FILE2')/Shelfmark"/>
I get nothing when I do the look-up.

Also correct, because you must not access File2 when declaring the key.


Am I supposed to build the key in File2, and if so, how do I then preserve it for use in File1.

Declaring a key creates a key table for every input file. It is the third argument of the key() function that declares which file is looked up ... and if the third argument is absent the tree of the current node is used (which you don't want because that is File1).


Sorry to be so dense, but I have never used keys before.

Did you try the code that I gave you? I was expecting it to work without you making any changes.


At 2015-09-05 23:54 +0000, you wrote:
My last was not quite right: I am building the key in the stylesheet that processes File 1.

The act of declaring a key will create a key table for every input file.


PS. Lost your book when my last computer went south.

All registered users get perpetual free updates ... I'll send you the password.


. . . . . . . Ken


-- Check our site for free XML, XSLT, XSL-FO and UBL developer resources | Free 5-hour lecture: http://www.CraneSoftwrights.com/links/video.htm | Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ | G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx | Google+ profile: http://plus.google.com/+GKenHolman-Crane/about | Legal business disclaimers: http://www.CraneSoftwrights.com/legal |


--- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus

Current Thread