1

テーブルに出力されているデータが 2 つの列に (事実上) 分割されている xml ファイルがあります。これはXMLです

<structuredBody>
  <component>
    <section>
      <templateId root="2.16.840.1.113883.10.20.22.2.3.1" />
      <entry>
        <organizer>
          <component>
            <observation>
              <code displayName="TIBC" />
              <effectiveTime value="8/29/2013 12:00:00 AM" />
              <value value="39" />
              <referenceRange>
                <observationRange>
                  <text />
                </observationRange>
              </referenceRange>
            </observation>
          </component>
        </organizer>
      </entry>
      <entry>
        <organizer>
          <component>
            <observation>
              <code displayName="TSAT" />
              <effectiveTime value="8/29/2013 12:00:00 AM" />
              <value value="25" />
              <referenceRange>
                <observationRange>
                  <text />
                </observationRange>
              </referenceRange>
            </observation>
          </component>
        </organizer>
      </entry>
      <entry>
        <organizer>
          <component>
            <observation>
              <code displayName="Albumin" />
              <effectiveTime value="9/5/2013 12:00:00 AM" />
              <value value="46" />
              <referenceRange>
                <observationRange>
                  <text />
                </observationRange>
              </referenceRange>
            </observation>
          </component>
        </organizer>
      </entry>
      <entry>
        <organizer>
          <component>
            <observation>
              <code displayName="ALT" />
              <effectiveTime value="9/5/2013 12:00:00 AM" />
              <value value="48" />
              <referenceRange>
                <observationRange>
                  <text>21-72</text>
                </observationRange>
              </referenceRange>
            </observation>
          </component>
        </organizer>
      </entry>
      <entry>
        <organizer>
          <component>
            <observation>
              <code displayName="Bicarbonate" />
              <effectiveTime value="9/5/2013 12:00:00 AM" />
              <value value="69" />
              <referenceRange>
                <observationRange>
                  <text />
                </observationRange>
              </referenceRange>
            </observation>
          </component>
        </organizer>
      </entry>
    </section>
  </component>
  <component>
    <section>
      <...>
    </section>
  </component>
  <component>
    <section>
      <...>
    </section>
  </component>
</structuredBody>

xslt を使用してフォーマットされた出力を取得しました。

<xsl:template match="/">
    <xsl:if test="//section[templateId/@root='2.16.840.1.113883.10.20.22.2.3.1']!=''">
        <xsl:variable name="rowLabs" select="ceiling(count(//section[templateId/@root='2.16.840.1.113883.10.20.22.2.3.1']/entry) div $colLabs)" />

        <div style="margin-bottom: 5px; padding: 5px; border-bottom: 1px solid #000000;">
            <span style="font-weight: bold;">Lab Results:</span>
            <table border="0" cellspacing="0" cellpadding="1" width="99%" style="font-size: 11px;">
                <xsl:for-each select="//section[templateId/@root='2.16.840.1.113883.10.20.22.2.3.1']/entry[position() &lt;= $rowLabs]">
                    <tr>
                        <xsl:variable name="otherEntries" select=".|following-sibling::entry[position() mod $rowLabs = 0]" />
                        <xsl:apply-templates select="self::*|$otherEntries" />
                        <xsl:call-template name="blankentries">
                            <xsl:with-param name="entries" select="$colLabs - count($otherEntries) - 1" />
                        </xsl:call-template>
                        <!--<xsl:apply-templates select=".|following-sibling::entry[position() &lt; 2]" />-->
                    </tr>
                </xsl:for-each>
            </table>
        </div>
    </xsl:if>
</xsl:template>

<xsl:template match="section[templateId/@root='2.16.840.1.113883.10.20.22.2.3.1']/entry">
    <td width="75">
        <xsl:call-template name="StripTime">
            <xsl:with-param name="DateTime" select="organizer/component/observation/effectiveTime/@value" />
        </xsl:call-template>
    </td>
    <td width="198">
        <xsl:value-of select="organizer/component/observation/code/@displayName"/>
    </td>
    <td width="50">
        <xsl:value-of select="organizer/component/observation/value/@value"/>
    </td>
    <td width="75">
        <xsl:value-of select="organizer/component/observation/referenceRange/observationRange/text"/>
    </td>
</xsl:template>

<xsl:template name="blankentries">
    <xsl:param name="entries" />
    <xsl:if test="$entries > 0">
        <td></td>
        <xsl:call-template name="blankentries">
            <xsl:with-param name="entries" select="$entries - 1" />
        </xsl:call-template>
    </xsl:if>
</xsl:template>

結果のエントリノードが実行されてから実行されるため、出力は次のようになります。

<table>
  <tr>
    <td>8/29/2013</td>
    <td>TIBC</td>
    <td>39</td>
    <td></td>
    <td>9/5/2013</td>
    <td>ALT</td>
    <td>48</td>
    <td>21-72</td>
  </tr>
  <tr>
    <td>8/29/2013</td>
    <td>TSAT</td>
    <td>25</td>
    <td></td>
    <td>9/5/2013</td>
    <td>Bicarbonate</td>
    <td>69</td>
    <td></td>
  </tr>
  <tr>
    <td>9/5/2013</td>
    <td>Albumin</td>
    <td>46</td>
    <td></td>
  </tr>
</table>

これは私に与えます:

[entry 1] [entry 4]
[entry 2] [entry 5]
[entry 3]

これは私が探しているものであり、それは素晴らしいことです。

私が理解できないのは、異なる 4 セルのエントリ セットを通過するときに別の色にする方法です。テーブルで目的の出力順序を取得するために操作しているため、position() を使用できません。数学を理解するために位置を出力すると、左側の列は常に「1」で、右側の列は常に「2」であるため、スタイル属性を設定するために position() mod 2 = 1 を実行できません.

次に、日付の値を 1 回だけ表示し、変更するまで表示しないようにします。これにより、出力は理想的には次のようになります。

<table>
  <tr>
    <td>8/29/2013</td>
    <td>TIBC</td>
    <td>39</td>
    <td></td>
    <td bgcolor="dcdcdc"></td>
    <td bgcolor="dcdcdc">ALT</td>
    <td bgcolor="dcdcdc">48</td>
    <td bgcolor="dcdcdc">21-72</td>
  </tr>
  <tr>
    <td bgcolor="dcdcdc"></td>
    <td bgcolor="dcdcdc">TSAT</td>
    <td bgcolor="dcdcdc">25</td>
    <td bgcolor="dcdcdc"></td>
    <td></td>
    <td>Bicarbonate</td>
    <td>69</td>
    <td></td>
  </tr>
  <tr>
    <td>9/5/2013</td>
    <td>Albumin</td>
    <td>46</td>
    <td></td>
  </tr>
</table>

「tr」タグに bgcolor 属性を配置することはできません。これは、行全体だけでなく、「列」全体でも交互に配置する必要があるためです。

助けてくれてありがとう。このサイトは、私の xslt に関する知識を大いに深めてくれました。私は先月、それを掘り下げ始めたばかりです。

4

1 に答える 1

1

$rowLabs色については、奇数か偶数かに応じて、基本的に 2 つのケースがあります。

  • 偶数の場合、奇数行は完全に「白」になり、偶数行は完全に「黒」になります。
  • 変だったら
    • 奇数行の場合、奇数列は白、偶数列は黒になります
    • 偶数行の場合、奇数列は黒、偶数列は白になります

(「奇数」と「偶数」は XPath と同じように 1 からカウントされるposition()ため、最初の行/列は奇数、2 番目は偶数など)。

テンプレートにいくつかのパラメーターを追加することで、XSLT でそのロジックをエンコードできます。を交換してください

<xsl:apply-templates select="self::*|$otherEntries" />

<xsl:apply-templates select="self::*|$otherEntries">
    <xsl:with-param name="rowNum" select="position()" />
    <xsl:with-param name="totalRows" select="$rowLabs" />
</xsl:apply-templates>

sectionパラメータをテンプレートに追加します

<xsl:template match="section[templateId/@root='2.16.840.1.113883.10.20.22.2.3.1']/entry">
    <xsl:param name="rowNum" select="1" />
    <xsl:param name="totalRows" select="2" />

ここで、上で説明したロジックを実装するために呼び出すことができる名前付きテンプレートが必要です。

<xsl:template name="bgcolor">
    <xsl:param name="rowNum" select="1" />
    <xsl:param name="totalRows" select="2" />
    <xsl:if test="($totalRows mod 2 = 0 and $rowNum mod 2 = 0) or
                  ($totalRows mod 2 = 1 and $rowNum mod 2 != position() mod 2)">
        <xsl:attribute name="bgcolor">dcdcdc</xsl:attribute>
    </xsl:if>
</xsl:template>

これにより、bgcolor行数が偶数で現在のrownumが偶数の場合、または行数が奇数で行内の現在の番号が行番号とは「異なる奇数」である場合に属性が追加されます。

最後に、<td>要素内でこのテンプレートを呼び出します。

<td width="50">
    <xsl:call-template name="bgcolor">
        <xsl:with-param name="rowNum" select="$rowNum" />
        <xsl:with-param name="totalRows" select="$totalRows" />
    </xsl:call-template>
    <xsl:value-of select="organizer/component/observation/value/@value"/>
</td>

このすべてを機能させる重要なことは、テンプレートをself::*|$otherEntriesに適用しているという事実です。したがって、適用されたテンプレート内で を呼び出すとposition()、親でのノードの元の位置ではなく、列番号 (このノード リスト内の位置) が得られます。


日付が最初に検出されたときに 1 回だけ表示されるようにするには、キーを定義し、"Muenchian grouping" 手法に関連するトリックを使用できます。宣言する

<xsl:key name="effectiveTimeByDate" match="effectiveTime"
         use="substring-before(@value, ' ')" />

次に、これがドキュメント内の特定の日付の最初の出現かどうかを確認できます

<td width="75">
    <xsl:call-template name="bgcolor">
        <xsl:with-param name="rowNum" select="$rowNum" />
        <xsl:with-param name="totalRows" select="$totalRows" />
    </xsl:call-template>
    <xsl:if test="
         generate-id(organizer/component/observation/effectiveTime)
       = generate-id(key('effectiveTimeByDate', substring-before(
            organizer/component/observation/effectiveTime/@value, ' '))[1])">
        <xsl:call-template name="StripTime">
            <xsl:with-param name="DateTime" select="organizer/component/observation/effectiveTime/@value" />
        </xsl:call-template>
    </xsl:if>
</td>

StripTime(テンプレートを完全に破棄しsubstring-beforeて、キーで使用しているものと同じ呼び出しを使用できる場合があります)

于 2013-09-10T18:26:28.327 に答える