即使您已经接受了一个答案,我也会毫不犹豫地接受...因为到目前为止,我认为其他任何一种解决方案都不正确(尽管一个与给定的示例输出匹配)。
这是我的实现:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0" xmlns:p="p">
<xsl:output method="text" />
<xsl:template match="/p:persons">
<xsl:apply-templates select="*[1]">
<xsl:with-param name="i" select="1" />
</xsl:apply-templates>
</xsl:template>
<!-- This template is applied to an element whenever it is
for a new person, i.e. when there is not a preceding
sibling element belonging to the same person. -->
<xsl:template match="p:forename | p:surname">
<xsl:param name="i"/>
<xsl:variable name="next" select="following-sibling::*[1]"/>
<xsl:variable name="surname" select="if (self::p:surname) then . else
if ($next[self::p:surname]) then $next else 'UNKNOWN'"/>
<xsl:variable name="forename" select="if (self::p:forename) then . else
if ($next[self::p:forename]) then $next else 'UNKNOWN'"/>
<xsl:value-of select="concat(if ($i > 1) then ' ' else '',
'--- Person', $i, '--- surname: ',
$surname, ' forename: ', $forename, ' ')"/>
<xsl:choose>
<xsl:when test="local-name($next) = local-name(.)">
<!-- Only one name is supplied. Start processing
the next sibling as a new person. -->
<xsl:apply-templates select="following-sibling::*[1]">
<xsl:with-param name="i" select="$i + 1"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<!-- Both names are supplied. Skip the second name
and start processing the sibling after it.-->
<xsl:apply-templates select="following-sibling::*[2]">
<xsl:with-param name="i" select="$i + 1"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
我对不完整规范的解释是:从第一个名字/姓氏元素开始。如果前两个元素是名字和姓氏(以任意顺序),则将两者都用于第一人称,然后将第三个元素作为新人开始处理。
否则,使用第一个元素并为未提供的名称提供“未知”。然后作为新人开始处理下一个元素。
有了这个规范解释,我很确定如果没有某种递归就不可能正确实现,因为每个元素与前面或后面的关联可能取决于前面的关联方式(例如,名字在前?),这可能取决于之前的人,等等。
上面的第一个示例输入给出了所需的输出。
第二个(标签更正)给出:
--- Person1---
surname: Surname1
forename: Forename1
--- Person2---
surname: UNKNOWN
forename: Forename2
一个更完整的例子:
<p:persons xmlns:p="p">
<p:surname>Surname1</p:surname>
<p:forename>Forename1</p:forename>
<p:surname>Surname2</p:surname>
<p:surname>Surname3</p:surname>
<p:surname>Surname4</p:surname>
<p:forename>Forename4</p:forename>
<p:forename>Forename5</p:forename>
<p:surname>Surname5</p:surname>
</p:persons>
给予
--- Person1---
surname: Surname1
forename: Forename1
--- Person2---
surname: Surname2
forename: UNKNOWN
--- Person3---
surname: Surname3
forename: UNKNOWN
--- Person4---
surname: Surname4
forename: Forename4
--- Person5---
surname: Surname5
forename: Forename5