XSLT合并XML文件:为<w>节点添加<entite_nom>属性时id为空问题
Fixing Empty
id Attribute When Merging TEI XML with Geolocation Data via XSLT Let's break down why your id attribute is coming up empty and fix it step by step.
The Core Issues in Your Current Code
- Namespace Misalignment: Your source TEI XML uses the
http://www.tei-c.org/ns/1.0namespace, but your XSLT doesn't declare or reference it properly. This means yourtei:nameandtei:wselectors aren't actually matching anything under the hood. - Key Matching Mismatch: Your
<xsl:key>is set to matchentite_nomby its text content (use="."), but when you callkey('ref', w[@type], $doc2), you're passing the attribute value ofw[@type](which is "NAM") instead of the text content of the<w>element (which is "Cussac"). That's why no matches are found, leading to an emptyid. - Typos: You have a typo in your
$pathvariable (coodinstead ofcoord) which will break yourrefattribute path.
Corrected XSLT Code
Here's the fixed version with explanations in comments:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:tei="http://www.tei-c.org/ns/1.0" <!-- Declare TEI namespace --> exclude-result-prefixes="tei"> <xsl:output method="xml" encoding="UTF-8" indent="yes"/> <!-- Fix typo in path --> <xsl:variable name="path" select="'file:fr_Cussac-coord-entites.xml'"/> <!-- Define key to match entite_nom by its text content, scoped to the second document --> <xsl:key name="ref" match="entite_nom" use="normalize-space(.)"/> <!-- Load the second XML document --> <xsl:param name="doc2" select="document($path)/geolocalisation"/> <!-- Shallow copy all nodes by default --> <xsl:mode on-no-match="shallow-copy"/> <!-- Match <tei:name> elements that contain a <tei:w> with type "NAM" --> <xsl:template match="tei:name[tei:w[@type='NAM']]"> <!-- Get the text content of the <w> element (trim whitespace) --> <xsl:variable name="place-text" select="normalize-space(tei:w[@type='NAM'])"/> <!-- Find the corresponding entite_nom in the second document --> <!-- Note: If multiple entite_nom have the same text, this picks the first one. To match sequentially, you'd need to track positions - let me know if you need that! --> <xsl:variable name="matched-entite" select="key('ref', $place-text, $doc2)[1]"/> <!-- Create the placeName element with id and ref attributes --> <placeName id="{$matched-entite/@id}" ref="{$path}"> <!-- Copy the original <name> content --> <xsl:copy-of select="."/> </placeName> </xsl:template> </xsl:stylesheet>
Key Fixes Explained
- Namespace Declaration: Adding
xmlns:tei="http://www.tei-c.org/ns/1.0"ensures we correctly target elements in the TEI namespace. - Correct Key Matching: We use
normalize-space(tei:w[@type='NAM'])to get the clean text of the place name (e.g., "Cussac") and pass that to the key, which matches against the text ofentite_nom. - Handling Duplicates: Since your second XML has multiple
entite_nomentries for "Cussac", we add[1]to pick the first matching entry. If you need to map each occurrence in the TEI to the corresponding entry in the geolocation file (e.g., first "Cussac" toen.0, second toen.6, etc.), we'd need to adjust the code to track position—just ask! - Typo Fix: Corrected
coodtocoordin the$pathvariable.
Expected Output
For each <tei:name> containing "Cussac", you'll now get:
<placeName id="en.0" ref="file:fr_Cussac-coord-entites.xml"> <name> <w type="NAM">Cussac</w> </name> </placeName>
内容的提问来源于stack exchange,提问作者Sat
相关产品推荐
相关产品推荐

