问题
I have tei-xml files where I've marked up named entities within medieval documents, in particular people's names using <persName/>
. A simple example:
<persName nymref="#Bernard_Faure_Senior">Bernardus Fabri senior</persName>
However, there are often names in the manuscript where I need to mark up "Raimunda uxor Bernardi Fabri" (ie "Raimunda, wife of Bernard Faure"). Here I markup both names, in nested fashion:
<persName nymref="#Raimunda_Faure">Raimunda uxor
<persName nymref="#Bernard_Faure_Senior">Bernardi Fabri
senior</persName></persName>
Generally this isn't a problem for querying the data. However, I want to output via XSLT 2.0 the following for a webpage, where each name is turned into a URL pointing to that person's own webpage (using @nymRef
). The above should output to this:
<a href="www.foo.com/person/Raimunda_Faure">Raimunda
uxor</a><a href="www.foo.com/person/Bernard_Faure_Senior">Bernardi
Fabri<a>
(ie. ...etiam nec tortor erat Raimunda uxor Bernardi Fabri est leo cursus magna, maximus finibus...)
Moreover, there are times where the following occurs (two names nested in one):
<persName nymref="#Raimunda_Faure">Raimunda uxor
<persName nymref="#Bernard_Faure_Senior">Bernardi Fabri
senior</persName> matris
<persName nymRef="Bernard_Faure_Junior">Bernardi
junior</persName></persName>
(Although there is never a case where <persName>
is nested three-deep)
I'm utterly lost as to how recursively differentiate and treat //persName[x]
and //persname[x]//persName[x]
in order to make them separate URLs.
The url is generated from a static value + after-substring(//tei:persName/@nymRef,'#')
. Obviously a simple XSL statement returns a cardinality error:
concat('www.foo.com/person',after-substring(//tei:persName/@nymRef,'#'))
Many thanks in advance for any assistance.
回答1:
Assuming your XML looked like this...
<persName nymref="#Raimunda_Faure">Raimunda uxor
<persName nymref="#Bernard_Faure_Senior">Bernardi Fabri senior</persName> matris
<persName nymRef="Bernard_Faure_Junior">Bernardi junior</persName>
</persName>
Then you could achieve your aim by adding this template to your XSLT
<xsl:template match="persName">
<a href="www.foo.com/person/{substring-after(@nymref, '#')}">
<xsl:value-of select="text()[1]" />
</a>
<xsl:apply-templates select="node()[position() > 1]" />
</xsl:template>
(Although if you are dealing with TEI, you would need to account for namespaces).
This does assume no other types of tags in the name.
EDIT: If there are other tags in the name, try this template instead, which will wrap everything before the first persName
in the a
tag
<xsl:template match="persName">
<xsl:variable name="nested" select="persName[1]|persName[1]/following-sibling::node()" />
<a href="www.foo.com/person/{substring(@nymref, 2)}">
<xsl:apply-templates select="node() except $nested" />
</a>
<xsl:apply-templates select="$nested" />
</xsl:template>
来源:https://stackoverflow.com/questions/52834795/xsl-2-0-generating-distinct-urls-from-nested-elements