Problem: Loading Part of XML-File in Variable

Here should go questions about transforming XML with XSLT and FOP.
Andreas
Posts: 11
Joined: Wed Jan 16, 2019 6:49 pm

Problem: Loading Part of XML-File in Variable

Post by Andreas » Wed Mar 18, 2020 6:28 pm

Hello all,

I'm having trouble loading parts of an XML-File from an interface in a variable and reuse that variable later.

Here's what I'm trying to do: I want to extraxt information from a SRU-interface from the German National Library DNB with an ID that matches a certain criteria

https://services.dnb.de/sru/authorities ... =118580604

If the ID matches in a record with datafield[tag='035'] and subfield[@code='a'], then copy the ancestor record-element, store it in a variable and extract data from the record.

Code: Select all

<xsl:transform version="3.0" 
               xmlns="http://MyDefaultNamespace"
               xmlns:marc="http://www.loc.gov/MARC21/slim"
               xmlns:sru="http://www.loc.gov/zing/srw/"
               xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

  <xsl:output method="xml" indent="no" encoding="UTF-8"/>
  
  <xsl:template match="/">
  
    <xsl:variable name="DataToExtract">

      <xsl:call-template name="getInfoFromSRU">
        <xsl:with-param name="id" select="'118580604'"/>
      </xsl:call-template>

    </xsl:variable>

    <xsl:variable name="element">
      <element>
        <xsl:if test="$DataToExtract[normalize-space()]">
          <xsl:value-of select="$DataToExtract/marc:datafield[@tag='100']/marc:subfield[@code='a']"/>
        </xsl:if>
      </element>
    </xsl:variable>

    <xsl:result-document method="xml" indent="no" encoding="UTF-8">
    
      <record xmlns="http://MyDefaultNamespace"">
        <xsl:copy-of select="$element"/>
      </record>
    
    </xsl:result-document>

  </xsl:template>

  <xsl:template name="getInfoFromSRU">

    <xsl:param name="id"/>
    <xsl:param name="url" select="'https://services.dnb.de/sru/authorities?version=1.1&amp;operation=searchRetrieve&amp;recordSchema=MARC21-xml&amp;maximumRecords=100&amp;query='"/>
    <xsl:param name="URLsuffix"/>
    <xsl:param name="nextRecordPosition"/>


    <xsl:variable name="URLcomplete" select="doc(concat($url,$id,$URLsuffix,$nextRecordPosition))"/>

    <xsl:choose>
      <xsl:when test="$URLcomplete/sru:searchRetrieveResponse/sru:records/sru:record/sru:recordData/marc:record[./marc:datafield[@tag='035']/marc:subfield[@code='a' and starts-with(.,'(DE-588)')] = concat('(DE-588)',$id)]">
        <xsl:copy-of select="$URLcomplete/sru:searchRetrieveResponse/sru:records/sru:record/sru:recordData/marc:record[./marc:datafield[@tag='035']/marc:subfield[@code='a' and starts-with(.,'(DE-588)')]  = concat('(DE-588)',$id)]"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:call-template name="getInfoFromSRU">
          <xsl:with-param name="id" select="$id"/>
          <xsl:with-param name="url" select="$url"/>
          <xsl:with-param name="URLsuffix" select="'&amp;startRecord='"/>
          <xsl:with-param name="nextRecordPosition" select="$URLcomplete/sru:searchRetrieveResponse/sru:nextRecordPosition"/>
        </xsl:call-template>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>
</xsl:transform>
The problem is, that the variable seems to be empty and I can't adress an element unless I force it with

Code: Select all

<xsl:value-of select="$DataToExtract//*[name()='datafield' and @tag='100']/*[name()='subfield' and @code='a']/text()"/>
Has anyone any idea why the namespace declaration gets lost when I want to use it in the variable? It worked in the template.

Any hints would be very much appreciated!

Radu
Posts: 7029
Joined: Fri Jul 09, 2004 5:18 pm

Re: Problem: Loading Part of XML-File in Variable

Post by Radu » Fri Mar 20, 2020 9:12 am

Hi Andreas,

Unfortunately I cannot access the XML document you pointed to because it can only be accessed from certain IP addresses. So I am unable to test this on my side.
In general if this works *[name()='datafield' and @tag='100'] and this does not marc:datafield[@tag='100'] it would mean that the "marc" prefix was bound to the wrong namespace on the xsl:transform root element.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

Andreas
Posts: 11
Joined: Wed Jan 16, 2019 6:49 pm

Re: Problem: Loading Part of XML-File in Variable

Post by Andreas » Fri Mar 20, 2020 10:46 am

Good morning Radu, thanks for the reply!

I'm still not sure, where the problem is. I checked the namespace in the transformation with

Code: Select all

 <xsl:message select="namespace-uri($DataToExtract/*)"/> 
and it gave me the exact namespace I used for "marc".

Strangely engouh, when I saved the file from the interface und used doc('file:///C:...') the transformation worked with the namespaces.

Radu
Posts: 7029
Joined: Fri Jul 09, 2004 5:18 pm

Re: Problem: Loading Part of XML-File in Variable

Post by Radu » Fri Mar 20, 2020 10:49 am

Hi,

I don't know. If you can provide a sample test XML file content I could look more into this.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

Andreas
Posts: 11
Joined: Wed Jan 16, 2019 6:49 pm

Re: Problem: Loading Part of XML-File in Variable

Post by Andreas » Fri Mar 20, 2020 11:01 am

Here we go: attachment deleted

Thanks!
Last edited by Andreas on Fri Mar 20, 2020 1:51 pm, edited 1 time in total.

Radu
Posts: 7029
Joined: Fri Jul 09, 2004 5:18 pm

Re: Problem: Loading Part of XML-File in Variable

Post by Radu » Fri Mar 20, 2020 1:29 pm

Hi Andreas,

I modified your XSLT to point directly to the XML document you provided:

Code: Select all

<xsl:variable name="URLcomplete" select="doc('file:/C:/Users/radu_coravu/Desktop/authorities/authorities.xml')"/>
You are probably expecting the "$DataToExtract" variable to be a record element but I added this logging message:

Code: Select all

<xsl:message>Data to extract is document: <xsl:value-of select="$DataToExtract instance of document-node()"/></xsl:message>
and it seems that it is in fact a document node containing a "record" element. So the XPath should be something like:

Code: Select all

$DataToExtract/marc:record/marc:datafield
or from what I tested you can force the xsl:variable to evaluate to an xsl:element like this:

Code: Select all

<xsl:variable name="DataToExtract" as="element()">
and in this case it evaluates directly to a marc:record element.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

Andreas
Posts: 11
Joined: Wed Jan 16, 2019 6:49 pm

Re: Problem: Loading Part of XML-File in Variable

Post by Andreas » Fri Mar 20, 2020 1:50 pm

Hi Radu,

thanks for the reply.

I'm pretty sure I tinkered with marc:record as well and it didn't work at the time, before I posted the problem with reduced code (the whole script contains about 2500 lines).

When I executed the code in the original script this morning it worked again. I don't know.

Is it possible that Saxon "caches" code or data?

Radu
Posts: 7029
Joined: Fri Jul 09, 2004 5:18 pm

Re: Problem: Loading Part of XML-File in Variable

Post by Radu » Fri Mar 20, 2020 2:15 pm

Hi Andreas,

Saxon caches data during a single transformation (if for example you use the doc() function twice on the same XML document) but there should be no caching between transformations.

Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

Andreas
Posts: 11
Joined: Wed Jan 16, 2019 6:49 pm

Re: Problem: Loading Part of XML-File in Variable

Post by Andreas » Fri Mar 20, 2020 4:48 pm

Hi Radu,

the transformation works now. Thank you very much for the clarification about variable behaviour.

Stay healthy and have a nice weekend,

Andreas

Post Reply