Согласно комментариям:
что, если бы элементы не были в последовательном порядке?
В этом случае (при условии XSLT 1.0) вы можете использовать translate()
для получения идентификаторов элементов, а затем искать соответствующие элементы по правильному имени, построенному с использованием concat()
. Я бы изменил ось following-sibling::
на ../
(сокращение от parent::
), чтобы в конечном итоге поймать также элементы, предшествующие текущему firstname
.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="customers">
<MyCustomers>
<xsl:apply-templates select="*[starts-with(name(),'firstname')]"/>
</MyCustomers>
</xsl:template>
<xsl:template match="*[starts-with(name(),'firstname')]">
<xsl:variable name="id" select="translate(name(),'firstname','')"/>
<Customer>
<Name><xsl:value-of select="concat(.,' ',
../*[name()=concat('lastname',$id)])"/></Name>
<Sex><xsl:value-of select="../*[name()=concat('sex',$id)]"/></Sex>
</Customer>
</xsl:template>
</xsl:stylesheet>
Устаревший ответ
Предполагая фиксированную структуру входного документа, как показано в вопросе, отлично работающее преобразование XSLT 1.0:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="customers">
<MyCustomers>
<xsl:apply-templates select="*[starts-with(name(),'firstname')]"/>
</MyCustomers>
</xsl:template>
<xsl:template match="*[starts-with(name(),'firstname')]">
<Customer>
<Name><xsl:value-of select="concat(.,' ',
following-sibling::*[1]
[starts-with(name(),'lastname')])"/></Name>
<Sex><xsl:value-of select="following-sibling::*[2]
[starts-with(name(),'sex')]"/></Sex>
</Customer>
</xsl:template>
</xsl:stylesheet>
Небольшое объяснение
Вам нужна функция XPath 1.0 starts-with()
из-за печального названия тегов в вашем вводе XML. Вы можете использовать ось following-sibling::
, чтобы получить необходимые следующие родственные теги любого элемента, имя которого начинается с firstname
.
person
Emiliano Poggi
schedule
11.07.2011
code
разметку и тщательно продумайте свои сообщения. - person Jaques le Fraque   schedule 12.07.2011