XSLT:将 id 从一个文档分配给另一个迭代多个相同的值
XSLT: assign ids from one document to the other iterating over multiple same values
谁能帮我解决以下问题?我有两个 XML 文档。看起来像这样的 TEI:
<?xml version="1.0" encoding="UTF-8"?>
<text>
<body>
<div>
<head>IN ADVENTU DOMINI</head>
<div type="time:1">
<ab ana="#head">
<hi>aaaa</hi>
</ab>
</div>
</div>
<div>
<head>FERIA II.</head>
<div type="time:1">
<ab ana="#head">
<hi>bbbb</hi>
</ab>
</div>
</div>
<div>
<head>FERIA III.</head>
<div type="time:1">
<ab ana="#head">
<hi>cccc</hi>
</ab>
</div>
</div>
<div>
<head>DOMINICA</head>
<div type="time:1">
<ab ana="#head">
<hi>dddd</hi>
</ab>
</div>
</div>
<div>
<head>FERIA II.</head>
<div type="time:1">
<ab ana="#head">
<hi>eeee</hi>
</ab>
</div>
</div>
<div>
<head>FERIA III.</head>
<div type="time:1">
<ab ana="#head">
<hi>ffff</hi>
</ab>
</div>
</div>
</body>
</text>
和一个看起来像这样的 table:
<table>
<row>
<cell>IN ADVENTU DOMINI</cell>
<cell>1234</cell>
</row>
<row>
<cell>FERIA II.</cell>
<cell>1200</cell>
</row>
<row>
<cell>FERIA III.</cell>
<cell>1211</cell>
</row>
<row>
<cell>DOMINICA</cell>
<cell>1299</cell>
</row>
<row>
<cell>FERIA II.</cell>
<cell>9999</cell>
</row>
<row>
<cell>FERIA III.</cell>
<cell>8888</cell>
</row>
</table>
现在我想将 ID(在 table 的第二个 <cell>
元素中找到)添加到 TEI 中与 <head>
中具有相同值的那些元素table 的第一个 <cell>
元素。我编写了以下 XSLT:
<xsl:template match="t:head">
<xsl:variable name="pos" select="count(current())"/>
<xsl:variable name="ids" select="document('feasts.xml')"/>
<xsl:variable name="row" select="$ids//row[cell[1]=current()][position()=$pos]"/>
<xsl:copy>
<xsl:if test="$row!=''">
<xsl:attribute name="xml:id">
<xsl:text>CDB.</xsl:text><xsl:value-of select="$row/cell[2]"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:copy>
</xsl:template>
我知道我必须对 $pos 变量做些什么,但我不知道如何从 table 而不仅仅是第一个中获取正确的 ID。 <head>
元素的期望输出为:
<head xml:id="CDB.1234">IN ADVENTU DOMINI</head>
<head xml:id="CDB.1200">FERIA II.</head>
<head xml:id="CDB.1211">FERIA III.</head>
<head xml:id="CDB.1299">DOMINICA</head>
<head xml:id="CDB.9999">FERIA II.</head>
<head xml:id="CDB.8888">FERIA III.</head>
最好使用 键 来解析交叉引用:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="ids" select="document('feasts.xml')"/>
<xsl:key name="grp" match="head" use="." />
<xsl:key name="id" match="row" use="cell[1]" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="head">
<xsl:variable name="i" select="index-of(key('grp', .)/generate-id(), generate-id())"/>
<head xml:id="CDB.{key('id', ., $ids)[$i]/cell[2]}">
<xsl:value-of select="."/>
</head>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<text>
<body>
<div>
<head xml:id="CDB.1234">IN ADVENTU DOMINI</head>
<div type="time:1">
<ab ana="#head">
<hi>aaaa</hi>
</ab>
</div>
</div>
<div>
<head xml:id="CDB.1200">FERIA II.</head>
<div type="time:1">
<ab ana="#head">
<hi>bbbb</hi>
</ab>
</div>
</div>
<div>
<head xml:id="CDB.1211">FERIA III.</head>
<div type="time:1">
<ab ana="#head">
<hi>cccc</hi>
</ab>
</div>
</div>
<div>
<head xml:id="CDB.1299">DOMINICA</head>
<div type="time:1">
<ab ana="#head">
<hi>dddd</hi>
</ab>
</div>
</div>
<div>
<head xml:id="CDB.9999">FERIA II.</head>
<div type="time:1">
<ab ana="#head">
<hi>eeee</hi>
</ab>
</div>
</div>
<div>
<head xml:id="CDB.8888">FERIA III.</head>
<div type="time:1">
<ab ana="#head">
<hi>ffff</hi>
</ab>
</div>
</div>
</body>
</text>
谁能帮我解决以下问题?我有两个 XML 文档。看起来像这样的 TEI:
<?xml version="1.0" encoding="UTF-8"?>
<text>
<body>
<div>
<head>IN ADVENTU DOMINI</head>
<div type="time:1">
<ab ana="#head">
<hi>aaaa</hi>
</ab>
</div>
</div>
<div>
<head>FERIA II.</head>
<div type="time:1">
<ab ana="#head">
<hi>bbbb</hi>
</ab>
</div>
</div>
<div>
<head>FERIA III.</head>
<div type="time:1">
<ab ana="#head">
<hi>cccc</hi>
</ab>
</div>
</div>
<div>
<head>DOMINICA</head>
<div type="time:1">
<ab ana="#head">
<hi>dddd</hi>
</ab>
</div>
</div>
<div>
<head>FERIA II.</head>
<div type="time:1">
<ab ana="#head">
<hi>eeee</hi>
</ab>
</div>
</div>
<div>
<head>FERIA III.</head>
<div type="time:1">
<ab ana="#head">
<hi>ffff</hi>
</ab>
</div>
</div>
</body>
</text>
和一个看起来像这样的 table:
<table>
<row>
<cell>IN ADVENTU DOMINI</cell>
<cell>1234</cell>
</row>
<row>
<cell>FERIA II.</cell>
<cell>1200</cell>
</row>
<row>
<cell>FERIA III.</cell>
<cell>1211</cell>
</row>
<row>
<cell>DOMINICA</cell>
<cell>1299</cell>
</row>
<row>
<cell>FERIA II.</cell>
<cell>9999</cell>
</row>
<row>
<cell>FERIA III.</cell>
<cell>8888</cell>
</row>
</table>
现在我想将 ID(在 table 的第二个 <cell>
元素中找到)添加到 TEI 中与 <head>
中具有相同值的那些元素table 的第一个 <cell>
元素。我编写了以下 XSLT:
<xsl:template match="t:head">
<xsl:variable name="pos" select="count(current())"/>
<xsl:variable name="ids" select="document('feasts.xml')"/>
<xsl:variable name="row" select="$ids//row[cell[1]=current()][position()=$pos]"/>
<xsl:copy>
<xsl:if test="$row!=''">
<xsl:attribute name="xml:id">
<xsl:text>CDB.</xsl:text><xsl:value-of select="$row/cell[2]"/>
</xsl:attribute>
</xsl:if>
<xsl:apply-templates select="*|@*|text()"/>
</xsl:copy>
</xsl:template>
我知道我必须对 $pos 变量做些什么,但我不知道如何从 table 而不仅仅是第一个中获取正确的 ID。 <head>
元素的期望输出为:
<head xml:id="CDB.1234">IN ADVENTU DOMINI</head>
<head xml:id="CDB.1200">FERIA II.</head>
<head xml:id="CDB.1211">FERIA III.</head>
<head xml:id="CDB.1299">DOMINICA</head>
<head xml:id="CDB.9999">FERIA II.</head>
<head xml:id="CDB.8888">FERIA III.</head>
最好使用 键 来解析交叉引用:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="ids" select="document('feasts.xml')"/>
<xsl:key name="grp" match="head" use="." />
<xsl:key name="id" match="row" use="cell[1]" />
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="head">
<xsl:variable name="i" select="index-of(key('grp', .)/generate-id(), generate-id())"/>
<head xml:id="CDB.{key('id', ., $ids)[$i]/cell[2]}">
<xsl:value-of select="."/>
</head>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<text>
<body>
<div>
<head xml:id="CDB.1234">IN ADVENTU DOMINI</head>
<div type="time:1">
<ab ana="#head">
<hi>aaaa</hi>
</ab>
</div>
</div>
<div>
<head xml:id="CDB.1200">FERIA II.</head>
<div type="time:1">
<ab ana="#head">
<hi>bbbb</hi>
</ab>
</div>
</div>
<div>
<head xml:id="CDB.1211">FERIA III.</head>
<div type="time:1">
<ab ana="#head">
<hi>cccc</hi>
</ab>
</div>
</div>
<div>
<head xml:id="CDB.1299">DOMINICA</head>
<div type="time:1">
<ab ana="#head">
<hi>dddd</hi>
</ab>
</div>
</div>
<div>
<head xml:id="CDB.9999">FERIA II.</head>
<div type="time:1">
<ab ana="#head">
<hi>eeee</hi>
</ab>
</div>
</div>
<div>
<head xml:id="CDB.8888">FERIA III.</head>
<div type="time:1">
<ab ana="#head">
<hi>ffff</hi>
</ab>
</div>
</div>
</body>
</text>