Peter
Peter

Reputation: 37

Troubleshooting XSLT namespace issue

I am trying to use XSLT to transform an XML document into a very similar XML document, but with a couple of additions. I'm having trouble getting xsl:copy-of to work properly. When I try to transform the following sample XML document:

<?xml version="1.0" encoding="UTF-8"?>
<mods xmlns="http://www.loc.gov/mods/v3" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xlink="http://www.w3.org/1999/xlink" 
xmlns:mods="http://www.loc.gov/mods/v3"
xsi:schemaLocation="http://www.loc.gov/mods/v3 
http://www.loc.gov/standards/mods/v3/mods-3-4.xsd">
  <titleInfo>
    <title>Test title
    </title>
  </titleInfo>
  <subject authority="naf">
    <geographic>Geo subject</geographic>
  </subject>
  <location>
    <physicalLocation>Location here</physicalLocation>
  </location>
  <originInfo>
    <dateCreated keyDate="yes">1904-01-05</dateCreated><dateCreated/>
  </originInfo>
  <typeOfResource>text</typeOfResource>
  <genre authority="aat" valueURI="300026880">correspondence</genre>
  <physicalDescription>
     <extent>3 pages.</extent>
     <note type="physical description">All pages ripped down the 
     middle. 
     </note>
  </physicalDescription>
  <relatedItem type="host" displayLabel="Collection" 
    <titleInfo>
      <title>Collection name</title>
    </titleInfo>
  </relatedItem>
  <accessCondition type="use and reproduction" displayLabel="Use and 
  Reproduction">Access condition here</accessCondition>
  <identifier type="local">IDID</identifier>
</mods>

Using the following XSLT, only the literal values in the XSLT (originInfo, accessCondition) are output in the result XML document. I can't figure out why this is. When I remove all the header info from the source XML, the transform DOES work. But all my XML files have that header, and I want to make the XSLT work with it in - my guess is that my namespace declarations are contradicting each other, but I can't figure out why.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xlink="https://www.w3.org/1999/xlink" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema" 
xmlns:mods="http://www.loc.gov/mods/v3" version="2.0" exclude- 
result-prefixes="mods">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/">
    <mods>
        <xsl:copy-of select="mods/titleInfo"/>
        <xsl:copy-of select="mods/typeOfResource"/>
        <xsl:copy-of select="mods/location"/>
        <xsl:copy-of select="mods/physicalDescription"/>
        <xsl:copy-of select="mods/subject"/>
        <xsl:copy-of select="mods/name"/>
        <xsl:copy-of select="mods/identifier"/>
        <xsl:copy-of select="mods/genre"/>
        <xsl:copy-of select="mods/relatedItem"/>
        <xsl:copy-of select="mods/accessCondition"/>
        <xsl:copy-of select="mods/language"/>
        <xsl:copy-of select="mods/abstract"/>
        <xsl:copy-of select="mods/note"/>
        <originInfo>
            <dateCreated>
              <xsl:value-of select="mods/originInfo/dateCreated"/> 
            </dateCreated>
            <dateCreated encoding="w3cdtf" keyDate="yes" 
            point="start">
              <xsl:value-of select="mods/originInfo/dateCreated"/>
            </dateCreated> 
        </originInfo>
        <accessCondition type="use and reproduction">
            <xsl:text>Copyright statement here</xsl:text>
        </accessCondition>
    </mods>         

</xsl:template>

My expected output is:

 <?xml version="1.0" encoding="UTF-8"?>
    <mods xmlns="http://www.loc.gov/mods/v3" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xlink="http://www.w3.org/1999/xlink" 
    xmlns:mods="http://www.loc.gov/mods/v3"
    xsi:schemaLocation="http://www.loc.gov/mods/v3 
    http://www.loc.gov/standards/mods/v3/mods-3-4.xsd">
      <titleInfo>
        <title>Test title
        </title>
      </titleInfo>
      <subject authority="naf">
        <geographic>Geo subject</geographic>
      </subject>
      <location>
        <physicalLocation>Location here</physicalLocation>
      </location>
      <typeOfResource>text</typeOfResource>
      <genre authority="aat" valueURI="300026880">correspondence</genre>
      <physicalDescription>
         <extent>3 pages.</extent>
         <note type="physical description">All pages ripped down the 
         middle. 
         </note>
      </physicalDescription>
      <relatedItem type="host" displayLabel="Collection" 
        <titleInfo>
          <title>Collection name</title>
        </titleInfo>
      </relatedItem>
      <accessCondition type="use and reproduction" displayLabel="Use and 
      Reproduction">Access condition here</accessCondition>
      <identifier type="local">IDID</identifier>
<originInfo>
      <dateCreated>1904-01-05 </dateCreated>
      <dateCreated encoding="w3cdtf" keyDate="yes" point="start">1904-01-05 </dateCreated>
   </originInfo>
   <accessCondition type="use and reproduction">Copyright statement here</accessCondition>
</mods>

Upvotes: 0

Views: 67

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117140

There are two problems with your XSLT:

  1. It does not select anything in the XML input, because your XML input puts its nodes in a namespace. If you're using XSLT 2.0, you can solve this by including xpath-default-namespace="http://www.loc.gov/mods/v3" in your xsl:stylesheet opening tag.

  2. It does not put the literal result elements in the target namespace. In order to do this, you must declare the target namespace as the default namespace in one of the higher-level nodes, e.g. by including xmlns="http://www.loc.gov/mods/v3" in your xsl:stylesheet opening tag.

In addition, in order to prevent the original namespace declarations being replicated to every element copied by your stylesheet, you would do well to replace the literal result element <mods> by a copy of the original one.

Here's a complete stylesheet incorporating these changes:

XSLT 2.0

<xsl:stylesheet  version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns="http://www.loc.gov/mods/v3"
xpath-default-namespace="http://www.loc.gov/mods/v3">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="/mods">
    <xsl:copy>
        <xsl:copy-of select="titleInfo"/>
        <xsl:copy-of select="typeOfResource"/>
        <xsl:copy-of select="location"/>
        <xsl:copy-of select="physicalDescription"/>
        <xsl:copy-of select="subject"/>
        <xsl:copy-of select="name"/>
        <xsl:copy-of select="identifier"/>
        <xsl:copy-of select="genre"/>
        <xsl:copy-of select="relatedItem"/>
        <xsl:copy-of select="accessCondition"/>
        <xsl:copy-of select="language"/>
        <xsl:copy-of select="abstract"/>
        <xsl:copy-of select="note"/>
        <originInfo>
            <dateCreated>
              <xsl:value-of select="originInfo/dateCreated"/> 
            </dateCreated>
            <dateCreated encoding="w3cdtf" keyDate="yes" point="start">
              <xsl:value-of select="originInfo/dateCreated"/>
            </dateCreated> 
        </originInfo>
        <accessCondition type="use and reproduction">
            <xsl:text>Copyright statement here</xsl:text>
        </accessCondition>
    </xsl:copy>        
</xsl:template>

</xsl:stylesheet>

Demo: http://xsltransform.hikmatu.com/gWmuiHV

Upvotes: 1

Related Questions