コメントによると:
要素が結果順序にない場合はどうなりますか?
この場合 (XSLT 1.0 を想定) を使用translate()
して要素の ID を取得し、 を使用して構築された正しい名前で対応する要素を検索できます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>
少し説明
starts-with()
XML入力のタグの名前が悲しいため、XPath 1.0関数が必要です。軸を使用してfollowing-sibling::
、名前が で始まる任意の要素の必要な次の兄弟タグを取得できますfirstname
。