0

動的 xml データを html テーブルに解析するときに問題が発生します。XML は次のとおりです。

<results>
  <result id="1" desc="Voltage and current">
    <measure desc="VOLT" value="1.0" />
    <measure desc="AMPERE" value="2.0" />
  </result>
  <result id="2" desc="Current-1">
    <measure desc="AMPERE" value="5.0" />
  </result>
</results>

そこから、次のようなhtmlテーブルが必要です:

ID   DESC                VOLT   AMPERE
1    Voltage and current 1.0    2.0
2    Current-1                  5.0

2 番目の電圧列の空のセルに注目してください。ID と DESC は result/@id と result/@desc から取得され、残りの列名は measure/@desc から取得される必要があります

列名は重複してはいけません。ここまでコード化できましたが、メジャーの追加を開始するときに、各メジャー/@desc を一致させてテーブル内の列を修正する必要があります。最初にすべての一意の列名に一致するように二重のネストされたループを試し、次にすべてのメジャーを再度ループして列ヘッダーに一致させました。しかし、xslt パーサーは私に NPE を投げました! 申し訳ありませんが、接続されていないコンピューター上にあるため、コードを表示できません。

ここSOで非常に多くのQ / Aを閲覧しましたが、特定の問題の助けにはなりません。

前もって感謝します

注: 誰かがより適切な形式を思いついた場合、解析を容易にするために XML 形式を任意の方法で変更することができます。

4

1 に答える 1

1

XSLT1.0 を使用している場合は、'Muenchian' グループ化と呼ばれる手法を使用して個別のメジャーの説明を取得できます。これは、ヘッド行の基礎を形成し、各行の値を出力するためにも使用されます。

まず、メジャー要素を@desc属性で検索するためのキーを定義します。

<xsl:key name="measures" match="measure" use="@desc" />

次に、個別のメジャーの説明を取得するために、指定された@desc属性のグループで最初に表示されるメジャー要素を反復処理できます。

<xsl:apply-templates 
   select="result/measure[generate-id() = generate-id(key('measures', @desc)[1])]"
   mode="header" />

次に、ヘッダーについては、説明を出力するためのテンプレートを用意するだけです。

<xsl:template match="measure" mode="header">
   <th>
      <xsl:value-of select="@desc" />
   </th>
</xsl:template>

結果行ごとに、同様のことを行い、すべての個別のメジャー値を反復処理しますが、唯一の違いは、後で使用するために、現在の結果要素をパラメーターとして渡す必要があることです。

<xsl:apply-templates 
   select="/results/result/measure[generate-id() = generate-id(key('measures', @desc)[1])]" 
   mode="data">
  <xsl:with-param name="result" select="." />
</xsl:apply-templates>

次に、今回メジャーに一致したテンプレートでは、一致する@desc属性を使用して結果要素内のメジャーにアクセスできます (また、id にはそのような属性がなく、セルには何も出力されません)。

<xsl:template match="measure" mode="data">
   <xsl:param name="result" />
   <td>
      <xsl:value-of select="$result/measure[@desc = current()/@desc]/@value" />
   </td>
</xsl:template>

ここに完全な XSLT があります

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="measures" match="measure" use="@desc" />

   <xsl:template match="/results">
      <table>
         <tr>
            <th>ID</th>
            <th>DESC</th>
            <xsl:apply-templates select="result/measure[generate-id() = generate-id(key('measures', @desc)[1])]" mode="header" />
         </tr>
         <xsl:apply-templates select="result" />
      </table>
   </xsl:template>

   <xsl:template match="result">
      <tr>
         <td><xsl:value-of select="@id" /></td>
         <td><xsl:value-of select="@desc" /></td>
         <xsl:apply-templates select="/results/result/measure[generate-id() = generate-id(key('measures', @desc)[1])]" mode="data">
            <xsl:with-param name="result" select="." />
         </xsl:apply-templates>
      </tr>
   </xsl:template>

   <xsl:template match="measure" mode="header">
      <th>
         <xsl:value-of select="@desc" />
      </th>
   </xsl:template>

   <xsl:template match="measure" mode="data">
      <xsl:param name="result" />
      <td>
         <xsl:value-of select="$result/measure[@desc = current()/@desc]/@value" />
      </td>
   </xsl:template>
</xsl:stylesheet>

異なる方法で機能する測定要素に一致する 2 つのテンプレートがあるため、モード属性の使用に注意してください。

入力 XML に適用すると、以下が出力されます。

<table>
   <tr>
      <th>ID</th>
      <th>DESC</th>
      <th>VOLT</th>
      <th>AMPERE</th>
   </tr>
   <tr>
      <td>1</td>
      <td>Voltage and current</td>
      <td>1.0</td>
      <td>2.0</td>
   </tr>
   <tr>
      <td>2</td>
      <td>Current-1</td>
      <td/>
      <td>5.0</td>
   </tr>
</table>
于 2012-11-02T15:43:54.113 に答える