これは少し洗練されていないソリューションであり、構造が異なるデータ セットに拡張するには追加の作業が必要になります (ただし、サンプル データ セットに配置された任意の数の serviceInfo 要素と serviceRequest 要素に対しては機能します)。その利点は、for-each ではなく適用テンプレートを使用することです。apply-templates を使用するのがベスト プラクティスです。また、使用する適切な名前空間がわからなかったので、いくつか作成しました。
この XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:foi="http://www.foi.com"
xmlns:rdf="http://www.rdf.com"
exclude-result-prefixes="foi rdf"
version="2.0">
<!-- Identity template -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:variable name="newLine"><xsl:text>
</xsl:text></xsl:variable>
<xsl:template match="/">
<xsl:value-of select="$newLine"/><table><xsl:value-of select="$newLine"/>
<xsl:apply-templates select="//foi:creationDate"/>
</table><xsl:value-of select="$newLine"/>
</xsl:template>
<xsl:template match="foi:creationDate">
<xsl:variable name="resourceId" select="replace(../foi:servicing/@rdf:resource,'#','')"/>
<xsl:message>BAH <xsl:value-of select="$resourceId"/></xsl:message>
<tr><xsl:value-of select="$newLine"/>
<td><xsl:apply-templates/></td><xsl:value-of select="$newLine"/>
<td><xsl:apply-templates select="//foi:serviceName[parent::*[@rdf:ID=$resourceId]]"/></td><xsl:value-of select="$newLine"/>
<td><xsl:apply-templates select="//foi:problemCode[parent::*[@rdf:ID=$resourceId]]"/></td><xsl:value-of select="$newLine"/>
<td><xsl:apply-templates select="//foi:division[parent::*[@rdf:ID=$resourceId]]"/></td><xsl:value-of select="$newLine"/>
</tr><xsl:value-of select="$newLine"/>
</xsl:template>
<xsl:template match="foi:serviceName">
<xsl:apply-templates select="@* | node()" />
</xsl:template>
<xsl:template match="foi:problemCode">
<xsl:apply-templates select="@* | node()" />
</xsl:template>
<xsl:template match="foi:division">
<xsl:apply-templates select="@* | node()" />
</xsl:template>
</xsl:stylesheet>
この XML ドキュメントに適用した場合: (注: ルート要素を追加しました)
<root>
<foi:serviceInfo rdf:ID="SI1">
<foi:serviceName>Sewer</foi:serviceName>
<foi:problemCode>SI1</foi:problemCode>
<foi:division>Water</foi:division>
</foi:serviceInfo>
<foi:serviceInfo rdf:ID="SI2">
<foi:serviceName>Recycling</foi:serviceName>
<foi:problemCode>SI2</foi:problemCode>
<foi:division>Solid Waste</foi:division>
</foi:serviceInfo>
<foi:serviceRequest rdf:ID="R1">
<foi:creationDate>29 03 2013</foi:creationDate>
<foi:servicing rdf:resource="#SI1"/>
</foi:serviceRequest>
<foi:serviceRequest rdf:ID="R2">
<foi:creationDate>29 06 2013</foi:creationDate>
<foi:servicing rdf:resource="#SI2"/>
</foi:serviceRequest>
</root>
望ましい結果が得られます。
<tr>
<td>29 03 2013</td>
<td>Sewer</td>
<td>SI1</td>
<td>Water</td>
</tr>
<tr>
<td>29 06 2013</td>
<td>Recycling</td>
<td>SI2</td>
<td>Solid Waste</td>
</tr>
</table>
簡単な説明:
- テキスト ノードを抑制します (テキスト ノードのデフォルトのテンプレートはそれらを出力するためのものです。XSLT ファイルの末尾にある特定のテンプレートを使用して出力します)。
- foi:creationDate要素の処理
- 各 foi:createDate 要素を処理するとき、その親である rdf:resource を見つけ、その値を変数に格納します
- 次に、親の rdf:ID が rdf:resource と一致するドキュメント (「//」が意味するもの) 内の各要素をすべて調べて見つかった適切な各要素を処理します (注: 一致する要素が複数ある場合、これは複数の値を出力します)。基準...あなたのデータセットにはそのような複数の要素はありませんでした; *は[おそらく] foi:serviceNameである可能性がありますが、*が何を意味するかを示したかった-任意の要素を選択し、[]内のものはどの要素を識別します合格できます)
- これにより、serviceName などの要素に子ノード (単なるテキスト ノード以外) を持たせ、それらを処理することもできます (ただし、現在、処理は結果ツリーにコピーされています)。