Reputation: 93
I'm processing a document and I need to generate xml:id attributes for select elements. I've run a modified identity transform on a scaled back sample document and I'm getting some extra attributes in the output. I think that it's a namespace issue but I'm not sure how to handle it.
I know that I should probably write templates for every potential element in the input document, but I don't know what all of them might be. Is there a way to handle this without resorting to writing an exhaustive template list?
Apologies if there's too much example; the problem in the output below is the part="N"
appearing in every <p>
. I'm using XSLT 2.0 and Saxon EE 9.5.0.2. Thanks for your time & trouble.
Input:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_lite.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?>
<?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_lite.rng" type="application/xml"
schematypens="http://purl.oclc.org/dsdl/schematron"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
<teiHeader>
<fileDesc>
<titleStmt>
<title>Title</title>
</titleStmt>
<publicationStmt>
<idno>1234</idno>
</publicationStmt>
<sourceDesc>
<p>Information about the source</p>
</sourceDesc>
</fileDesc>
</teiHeader>
<text>
<body>
<div type="book">
<div type="chapter" n="1">
<pb facs="003" n="1"/>
<head type="main">The Book's Title</head>
<head type="subhead">Chapter I.</head>
<p>Mauris suscipit ultricies odio, nec tincidunt justo laoreet et. Suspendisse nisi velit, dignissim et risus id, pulvinar rutrum tellus. Phasellus metus justo, lobortis eu lorem quis, tincidunt tempor ipsum. Proin suscipit suscipit massa. Sed nec bibendum sapien, id tempus metus. Nunc eu laoreet quam. Nam sagittis ac lorem sit amet venenatis.</p>
</div>
<div type="chapter" n="2">
<head type="subhead">Chapter 2.</head>
<pb facs="005" n="3"/>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis id ligula quis lacus sagittis luctus nec nec erat. Nunc in ultrices purus, a semper est. Fusce bibendum pharetra ornare. Donec tristique molestie eleifend. Mauris dignissim arcu sed urna auctor condimentum. Pellentesque rhoncus ante ut imperdiet consectetur. Duis blandit tortor dolor, ut mattis risus laoreet at. Donec eu dui ut enim pulvinar pharetra eu eget metus. In tortor ante, varius faucibus leo nec, malesuada aliquam neque. Quisque gravida, velit et iaculis tin/cidunt, quam augue condimentum purus, non elementum nisi magna vel odio.</p>
</div>
<div type="chapter" n="3">
<head type="subhead">Chapter 3.</head>
<pb facs="007" n="5"/>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis id ligula quis lacus sagittis luctus nec nec erat. Nunc in ultrices purus, a semper est. Fusce bibendum pharetra ornare. Donec tristique molestie eleifend. Mauris dignissim arcu sed urna auctor condimentum. Pellentesque rhoncus ante ut imperdiet consectetur. Duis blandit tortor dolor, ut mattis risus laoreet at. Donec eu dui ut enim pulvinar pharetra eu eget metus. In tortor ante, varius faucibus leo nec, malesuada aliquam neque. Quisque gravida, velit et iaculis tincidunt, quam augue condimentum purus, non elementum nisi magna vel odio.</p>
</div>
</div>
</body>
</text>
</TEI>
XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.tei-c.org/ns/1.0"
xpath-default-namespace="http://www.tei-c.org/ns/1.0"
exclude-result-prefixes="#all"
version="2.0">
<!-- adding xml:id values to P5 TEI -->
<!-- variables -->
<xsl:variable name="vID" select="/TEI/*/*/publicationStmt/idno[1]"/>
<xsl:variable name="vID-fileName" select="concat($vID, '_new.xml')"/>
<xsl:variable name="vID-primary" select="concat('ms', $vID)"/>
<!-- processing begins -->
<!-- identity transform -->
<!-- deep copy -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- add xml:id to document node -->
<xsl:template match="TEI">
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:id="{$vID-primary}">
<xsl:apply-templates/>
</TEI>
</xsl:template>
<!-- add xml:id to divs -->
<xsl:template match="div">
<div>
<xsl:if test="@type">
<xsl:attribute name="type">
<xsl:value-of select="@type"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="@n">
<xsl:attribute name="n">
<xsl:value-of select="@n"/>
</xsl:attribute>
</xsl:if>
<xsl:attribute name="xml:id">
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
<xsl:apply-templates/>
</div>
</xsl:template>
<xsl:template match="pb">
<xsl:variable name="vN" select="@n"/>
<xsl:variable name="vFacs" select="@facs"/>
<pb facs="{$vFacs}" n="{$vN}" xml:id="{generate-id(.)}"/>
</xsl:template>
</xsl:stylesheet>
Current output:
<?xml version="1.0" encoding="UTF-8"?><?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_lite.rng" type="application/xml" schematypens="http://relaxng.org/ns/structure/1.0"?><?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_lite.rng" type="application/xml"
schematypens="http://purl.oclc.org/dsdl/schematron"?><TEI xmlns="http://www.tei-c.org/ns/1.0" xml:id="ms1234">
<teiHeader type="text">
<fileDesc>
<titleStmt>
<title>Title</title>
</titleStmt>
<publicationStmt>
<idno>1234</idno>
</publicationStmt>
<sourceDesc default="false">
<p part="N">Information about the source</p>
</sourceDesc>
</fileDesc>
</teiHeader>
<text>
<body>
<div type="book" xml:id="d2e33">
<div type="chapter" n="1" xml:id="d2e35">
<pb facs="003" n="1" xml:id="d2e37"/>
<head type="main">The Book's Title</head>
<head type="subhead">Chapter I.</head>
<p part="N">Mauris suscipit ultricies odio, nec tincidunt justo laoreet et. Suspendisse nisi velit, dignissim et risus id, pulvinar rutrum tellus. Phasellus metus justo, lobortis eu lorem quis, tincidunt tempor ipsum. Proin suscipit suscipit massa. Sed nec bibendum sapien, id tempus metus. Nunc eu laoreet quam. Nam sagittis ac lorem sit amet venenatis.</p>
</div>
<div type="chapter" n="2" xml:id="d2e49">
<head type="subhead">Chapter 2.</head>
<pb facs="005" n="3" xml:id="d2e54"/>
<p part="N">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis id ligula quis lacus sagittis luctus nec nec erat. Nunc in ultrices purus, a semper est. Fusce bibendum pharetra ornare. Donec tristique molestie eleifend. Mauris dignissim arcu sed urna auctor condimentum. Pellentesque rhoncus ante ut imperdiet consectetur. Duis blandit tortor dolor, ut mattis risus laoreet at. Donec eu dui ut enim pulvinar pharetra eu eget metus. In tortor ante, varius faucibus leo nec, malesuada aliquam neque. Quisque gravida, velit et iaculis tin/cidunt, quam augue condimentum purus, non elementum nisi magna vel odio.</p>
</div>
<div type="chapter" n="3" xml:id="d2e60">
<head type="subhead">Chapter 3.</head>
<pb facs="007" n="5" xml:id="d2e65"/>
<p part="N">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis id ligula quis lacus sagittis luctus nec nec erat. Nunc in ultrices purus, a semper est. Fusce bibendum pharetra ornare. Donec tristique molestie eleifend. Mauris dignissim arcu sed urna auctor condimentum. Pellentesque rhoncus ante ut imperdiet consectetur. Duis blandit tortor dolor, ut mattis risus laoreet at. Donec eu dui ut enim pulvinar pharetra eu eget metus. In tortor ante, varius faucibus leo nec, malesuada aliquam neque. Quisque gravida, velit et iaculis tincidunt, quam augue condimentum purus, non elementum nisi magna vel odio.</p>
</div>
</div>
</body>
</text>
</TEI>
Upvotes: 1
Views: 102
Reputation: 4739
To answer you question of not writing out all of the elements where you want to add xml:id
you could replace the templates:
<!-- add xml:id to document node -->
<xsl:template match="TEI">
<TEI xmlns="http://www.tei-c.org/ns/1.0" xml:id="{$vID-primary}">
<xsl:apply-templates/>
</TEI>
</xsl:template>
<!-- add xml:id to divs -->
<xsl:template match="div">
<div>
<xsl:if test="@type">
<xsl:attribute name="type">
<xsl:value-of select="@type"/>
</xsl:attribute>
</xsl:if>
<xsl:if test="@n">
<xsl:attribute name="n">
<xsl:value-of select="@n"/>
</xsl:attribute>
</xsl:if>
<xsl:attribute name="xml:id">
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
<xsl:apply-templates/>
</div>
</xsl:template>
With:
<!-- add xml:id to all elements that do not need more adjustments -->
<xsl:template match="TEI | div">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:attribute name="xml:id">
<xsl:value-of select="generate-id(.)"/>
</xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
You can then extend the <xsl:template match="TEI | div">
with all elements you only want to place xml:id
extra in it. Elements where you want to place xml:id
and do other stuff can be written into a separate template or you add some kind of a xsl:choose
Regarding the <p part="N">
issue. This does not occur in Altova XMLSpy.
Upvotes: 1