xsl:apply-templates returns nothing − what am I missing?

Viewed 38

I have a simple XML response, like

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<searchRetrieveResponse xmlns="http://www.loc.gov/zing/srw/">
    <numberOfRecords>1</numberOfRecords>
    <records>
        <record>
            <recordData>
                <kitodo xmlns="http://meta.kitodo.org/v1/">
                    <metadata name="key1">value1</metadata>
                    <metadata name="key2">value2</metadata>
                    <metadata name="key3">value3</metadata>
                </kitodo>
            </recordData>
        </record>
    </records>
</searchRetrieveResponse>

which I want to transform to this by XSLT

<?xml version="1.0" encoding="utf-8"?>
<mets:mdWrap xmlns:kitodo="http://meta.kitodo.org/v1/"
              xmlns:mets="http://www.loc.gov/METS/"
              xmlns:srw="http://www.loc.gov/zing/srw/"
              MDTYPE="OTHER"
              OTHERMDTYPE="Kitodo">
    <mets:xmlData>
        <kitodo:kitodo>
            <kitodo:metadata name="key1">value1</kitodo:metadata>
            <kitodo:metadata name="key2">value2</kitodo:metadata>
            <kitodo:metadata name="key3">value3</kitodo:metadata>
        </kitodo:kitodo>    
    </mets:xmlData>
</mets:mdWrap>

That is, I want to remove the outside tree searchRetrieveResponse/records/record/recordData, replace it with mdWrap/xmlData and move the contained data node there. I have a quite short XSLT for it:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:kitodo="http://meta.kitodo.org/v1/" xmlns:mets="http://www.loc.gov/METS/" xmlns:srw="http://www.loc.gov/zing/srw/">
    <xsl:output method="xml" indent="yes" encoding="utf-8"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="srw:recordData">
        <mets:mdWrap MDTYPE="OTHER" OTHERMDTYPE="Kitodo">
            <mets:xmlData>
                <xsl:apply-templates select="@*|node()"/>
            </mets:xmlData>
        </mets:mdWrap>
    </xsl:template>

    <!-- pass-through rule -->
    <xsl:template match="@*|node()">
        <xsl:apply-templates select="@*|node()"/>
    </xsl:template>
</xsl:stylesheet>

However, what I get is:

<?xml version="1.0" encoding="utf-8"?>
<mets:mdWrap xmlns:kitodo="http://meta.kitodo.org/v1/"
              xmlns:mets="http://www.loc.gov/METS/"
              xmlns:srw="http://www.loc.gov/zing/srw/"
              MDTYPE="OTHER"
              OTHERMDTYPE="Kitodo">
   <mets:xmlData/>
</mets:mdWrap>

Obviously, the template match="srw:recordData" does match, otherwise I would get an empty result. However, the contained apply-templates doesn’t output anything. (I also tried an <xsl:apply-templates/> without a select="" attribute, but it doesn’t output anything either.) What am I missing?

XSLT processor is net.sf.saxon.TransformerFactoryImpl (Java)

2 Answers

I think nothing happens when you are applying templates inside xmlData. There are no templates that would match descendant nodes.

Try using copy-of:

<xsl:template match="srw:recordData">
    <mets:mdWrap MDTYPE="OTHER" OTHERMDTYPE="Kitodo">
        <mets:xmlData>
            <xsl:copy-of select="kitodo:kitodo"/>                
        </mets:xmlData>
    </mets:mdWrap>
</xsl:template>

The problem is not with the xsl:apply-templates instruction. It is with the template being applied. Your "pass-through rule" does not write anything to the output. You probably meant to have the identity transform template in that place - which goes like this:

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>
Related