I. この XSLT 2.0 変換:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<Employer>
<xsl:apply-templates/>
</Employer>
</xsl:template>
<xsl:template match="Employees">
<xsl:variable name="vNames" select="tokenize(Names, ' ')"/>
<xsl:variable name="vLoc" select="tokenize(Location, ' ')"/>
<xsl:variable name="vWeather"
select="tokenize(translate(Weather, '%', ' '), ' ')"/>
<xsl:for-each select="$vNames">
<xsl:variable name="vPos" select="position()" as="xs:integer"/>
<Employees>
<Names><xsl:sequence select="."/></Names>
<Location>
<xsl:sequence select="(lower-case($vLoc[$vPos]), 'Unknown')[1]"/>
</Location>
<Weather>
<xsl:sequence select="($vWeather[$vPos], 100)[1]"/>
</Weather>
</Employees>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
提供された XML ドキュメントに適用した場合:
<Employer>
<Employees>
<Names>vel bel sel tel mel</Names>
<Location>IND AUS ENG CAL JAP</Location>
<Weather>26%</Weather>
</Employees>
<Employees>
<Names>asd sadl asdsel tdddel dmdel</Names>
<Location>IND AUS ENG CAL JAP</Location>
</Employees>
</Employer>
必要な正しい結果が生成されます。
<Employer>
<Employees>
<Names>vel</Names>
<Location>ind</Location>
<Weather>26</Weather>
</Employees>
<Employees>
<Names>bel</Names>
<Location>aus</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>sel</Names>
<Location>eng</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>tel</Names>
<Location>cal</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>mel</Names>
<Location>jap</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>asd</Names>
<Location>ind</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>sadl</Names>
<Location>aus</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>asdsel</Names>
<Location>eng</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>tdddel</Names>
<Location>cal</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>dmdel</Names>
<Location>jap</Location>
<Weather>100</Weather>
</Employees>
</Employer>
注意してください:
私は次の合理的な仮定を立てました。
あなたが実際に望む100
のは、 ではありません100%
。
Employees
この要素の最初の出現だけでなく、すべてを処理する必要があります。
提供された場所の数が提供された名前の数よりも少ない場合に備えて、欠落している場所のデフォルト値も追加しました。
Ⅱ.XSLT 1.0 ソリューション:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common"
xmlns:my="my:my" exclude-result-prefixes="ext my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<my:defaults>
<L>Unknown</L>
<W>100</W>
</my:defaults>
<xsl:variable name="vUpper" select="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
<xsl:variable name="vLower" select="'abcdefghijklmnopqrstuvwxyz'"/>
<xsl:variable name="vDefaults" select="document('')/*/my:defaults"/>
<xsl:template match="/*">
<Employer>
<xsl:apply-templates/>
</Employer>
</xsl:template>
<xsl:template match="Employees">
<xsl:variable name="vrtfNames">
<xsl:apply-templates select="Names"/>
</xsl:variable>
<xsl:variable name="vNames" select="ext:node-set($vrtfNames)/*"/>
<xsl:variable name="vrtfLocs">
<xsl:apply-templates select="Location"/>
</xsl:variable>
<xsl:variable name="vrtfWeather">
<xsl:apply-templates select="Weather"/>
</xsl:variable>
<xsl:apply-templates select="$vNames">
<xsl:with-param name="pLocs" select="ext:node-set($vrtfLocs)/*"/>
<xsl:with-param name="pWeather" select="ext:node-set($vrtfWeather)/*"/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="s" priority="3">
<xsl:param name="pLocs"/>
<xsl:param name="pWeather"/>
<xsl:variable name="vPos" select="position()"/>
<Employees>
<Names><xsl:value-of select="."/></Names>
<Location>
<xsl:value-of select=
"translate($pLocs[position() = $vPos]
| $vDefaults[not($pLocs[position() = $vPos])]/L,
$vUpper, $vLower)"/>
</Location>
<Weather>
<xsl:value-of select=
"$pWeather[position() = $vPos]
| $vDefaults[not($pWeather[position() = $vPos])]/W"/>
</Weather>
</Employees>
</xsl:template>
<xsl:template match="Weather">
<xsl:call-template name="tokenize">
<xsl:with-param name="pText" select="translate(., '%', ' ')"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="Employees/*/text()" name="tokenize">
<xsl:param name="pText" select="."/>
<xsl:variable name="vText" select="normalize-space($pText)"/>
<xsl:if test="$vText">
<s>
<xsl:value-of select="substring-before(concat($vText, ' '), ' ')"/>
</s>
<xsl:call-template name="tokenize">
<xsl:with-param name="pText" select="substring-after($vText, ' ')"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
この変換が提供された XML ドキュメント (上記) に適用されると、同じように正しい結果が生成されます。
<Employer>
<Employees>
<Names>vel</Names>
<Location>ind</Location>
<Weather>26</Weather>
</Employees>
<Employees>
<Names>bel</Names>
<Location>aus</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>sel</Names>
<Location>eng</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>tel</Names>
<Location>cal</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>mel</Names>
<Location>jap</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>asd</Names>
<Location>ind</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>sadl</Names>
<Location>aus</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>asdsel</Names>
<Location>eng</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>tdddel</Names>
<Location>cal</Location>
<Weather>100</Weather>
</Employees>
<Employees>
<Names>dmdel</Names>
<Location>jap</Location>
<Weather>100</Weather>
</Employees>
</Employer>
注意してください:
基本的に、XSLT 2.0 変換と同じロジックが実装されています。
XPath 1.0 にはtokenize
orlower-case()
関数がなく、XPath 1.0 データ モデルにはシーケンスの概念がないため、これらは (それぞれ) トークン化のテンプレートを使用して実装され、translate()
小文字に変換する関数を使用し、要素を使用して実装されます。天気と場所のデフォルトが含まれています。