我有这个XML
<participants>
<event>Seminar</event>
<location>City somewhere</location>
<first_name>Carl</first_name>
<last_name>Smith</last_name>
<first_name>John</first_name>
<last_name>Somebody</last_name>
<first_name>Lisa</first_name>
<last_name>Lint</last_name>
<first_name>Gabriella</first_name>
<last_name>Whowho</last_name>
</participants>
我需要将其转换为:
<participants>
<event>Seminar</event>
<location>City somewhere</location>
<persons>
<person>
<given_name>Carl</given_name>
<surname>Smith</surname>
</person>
<person>
<given_name>John</given_name>
<surname>Somebody</surname>
</person>
<person>
<given_name>Lisa</given_name>
<surname>Lint</surname>
</person>
<person>
<given_name>Gabriella</given_name>
<surname>Whowho</surname>
</person>
</persons>
</participants>
人数可以是任何数字,有时可能有空元素(如果名字和姓氏都是空的,那么就不会创建这个人。
我很难开始这种转变。
如果您只是处理first_name
元素并使用 XPath 导航来选择其同级元素,则last_name
得到
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="participants">
<xsl:copy>
<xsl:apply-templates select="*[not(self::first_name | self::last_name)]"/>
<xsl:apply-templates select="first_name" mode="person"/>
</xsl:copy>
</xsl:template>
<xsl:template match="first_name" mode="person">
<xsl:variable name="surname" select="following-sibling::last_name[1]"/>
<xsl:if test="normalize-space() and normalize-space($surname)">
<person>
<xsl:apply-templates select=". | $surname"/>
</person>
</xsl:if>
</xsl:template>
<xsl:template match="first_name">
<given_name>
<xsl:apply-templates/>
</given_name>
</xsl:template>
<xsl:template match="last_name">
<surname>
<xsl:apply-templates/>
</surname>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/94AbWAW/1