Reputation: 11
I am working with large XML collections that have a lot of empty divs. I am writing an XSL file to (1) remove all div elements except for the first and (2) to insert the attribute value of into the attribute value of (the first div).
This is an example section from my source URL:
<text type="letter" xmlns="http://www.tei-c.org/ns/1.0">
<body>
<pb n="1" facs="stefansson-wrangel-09-21-010-001"/>
<div1 type="">
<p corresp="TTP32407168P0">
<add>
<hi rend="underline">Noice</hi>
</add>
</p>
<p corresp="TTP32407168P1">
<date when="1923-02-02">February 2, 1923</date>
</p>
<p corresp="TTP32407168P2">Dear Mr. <persName key="S32010887">Stefansson</persName>:
</p>
<p corresp="TTP32407168P3">
<persName key="S32010970">Joe Bernard</persName> left Monday. His present intention<lb/>
is to go to Boston, then on to Montreal, where he will spend the greater<lb/>
part of the winter. <persName key="S32010970">Joe</persName> plans to try to get museums, sportsmen, or anyone<lb/>
else to finance a trip to the Arctic, (preferably <placeName key="S32010957">Coronation Gulf</placeName>), although<lb/>
if he hears from you in the meantime he will go to <placeName key="S32010932">Wrangel</placeName>.
</p>
...
</div1>
I want
<div1 type="">
to be populated with "letter", from
<text type="letter">
Here is the XSL, which successfully removes all div1 elements except for the first:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.tei-c.org/ns/1.0"
xmlns="http://www.tei-c.org/ns/1.0"
version="3.0">
<xsl:output method="xml" indent="yes"/>
<xsl:variable name="genre" select="text/@type"></xsl:variable>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="div1[position()!=1]">
<xsl:apply-templates select="node()"/>
</xsl:template>
<xsl:template match="div1[position()=1]">
<xsl:attribute name="type">
<xsl:value-of select="$genre"/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
This results in an error message: "An attribute node (type) cannot be created after a child of the containing element. Most recent element start tag was output at line 12 of module remove-extra-divs.xsl"
Upvotes: 1
Views: 46
Reputation: 163262
Change the relevant template rule to
<xsl:template match="div1[position()=1]">
<div1>
<xsl:attribute name="type">
<xsl:value-of select="$genre"/>
</xsl:attribute>
<xsl:apply-templates/>
</div1>
</xsl:template>
or more concisely,
<xsl:template match="div1[position()=1]">
<div1 type="{$genre}">
<xsl:apply-templates/>
</div1>
</xsl:template>
Upvotes: 1