0

XMLファイルに以下のコードがあり、次の情報を行に表示したいとします。creationDate-serviceName-problemCode-division。

<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>

serviceRequestからの情報を行に表示することはできますが、foi:servicingのリソースをserviceInfoのIDにリンクする方法がわかりません(serviceInfoに含まれる属性を取得して、後で表示するため)。

4

3 に答える 3

1

これは少し洗練されていないソリューションであり、構造が異なるデータ セットに拡張するには追加の作業が必要になります (ただし、サンプル データ セットに配置された任意の数の 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 などの要素に子ノード (単なるテキスト ノード以外) を持たせ、それらを処理することもできます (ただし、現在、処理は結果ツリーにコピーされています)。
于 2013-02-02T21:27:01.643 に答える
1

この短い変換では、X 参照にキーを使用し、必要な結果をテーブルに生成します。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:foi="some:foi" xmlns:rdf="some:rdf" exclude-result-prefixes="foi rdf">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kSIById" match="foi:serviceInfo" use="concat('#',@rdf:ID)"/>

 <xsl:template match="/*">
  <table border="1"><xsl:apply-templates/></table>
 </xsl:template>
 <xsl:template match="/*/*" priority="-1"/>

 <xsl:template match="/*/foi:serviceRequest">
  <tr>
   <td><xsl:apply-templates select="foi:creationDate"/></td>
   <xsl:apply-templates select="key('kSIById', foi:servicing/@rdf:resource)/*"/>
  </tr>
 </xsl:template>

 <xsl:template match="foi:serviceInfo/*">
   <td><xsl:value-of select="."/></td>
 </xsl:template>
</xsl:stylesheet>

提供されたソース XML (単一の最上位要素にラップされ、名前空間が定義されている) に適用された場合:

<root xmlns:foi="some:foi" xmlns:rdf="some:rdf">
  <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>

必要な正しい結果が生成されます。

<table border="1">
   <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>
于 2013-02-03T16:43:20.233 に答える
0

XSLT でデータを相互参照するには、<xsl:key>. 次の XSLT はそれを行う必要があります。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:foi="foifoifoi" xmlns:rdf="rdfrdf"
                exclude-result-prefixes="foi rdf">
  <xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
  <xsl:key name="kService" match="foi:serviceInfo" use="@rdf:ID"/>

  <xsl:template match="/*">
    <div>
      <xsl:apply-templates select="foi:serviceRequest" />
    </div>
  </xsl:template>

  <xsl:template match="foi:serviceRequest">
    <xsl:variable name="referenceId"
                  select="substring(foi:servicing/@rdf:resource, 2)" />
    <xsl:variable name="info" select="key('kService', $referenceId)[1]"/>
    <div>
      <xsl:value-of select="foi:creationDate"/>
      <xsl:apply-templates select="$info/*" />
    </div>
  </xsl:template>

  <xsl:template match="foi:serviceInfo/*">
    <xsl:value-of select="concat(' - ', .)"/>
  </xsl:template>
</xsl:stylesheet>

(名前空間を指定しなかったので、名前空間を作成する必要がありました。適切な URI に置き換えてください) foirdfこの XML で実行すると (ルート ノードが追加されます):

<root xmlns:foi="foifoifoi" xmlns:rdf="rdfrdf">
  <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>

これにより、次が生成されます。

<div>
  <div>29 03 2013 - Sewer - SI1 - Water</div>
  <div>29 06 2013 - Recycling - SI2 - Solid Waste</div>
</div>

主なポイント:

  • 特定の によるxsl:key位置特定を可能にするための の使用。foi:serviceInfoID
  • IDkey()で関連を検索する関数の使用。foi:serviceInfo最後の[1]は、これを最初の一致に制限します。複数の試合がある可能性があるかどうかはわかりませんでしたが、ありますか?
  • foi:serviceInfoの子をハイフンと要素値としてレンダリングするテンプレート。
于 2013-02-03T03:01:09.750 に答える