0

私の xml データは半構造化されています。テキスト データと数値データをテーブルに転送する必要があります。さらに、数値データを比較し、2 つのテストを満たす場合は一致を色分けする必要があります。xml入力が高度に構造化されていない場合、達成可能かどうか疑問に思います。私の入力データは次のようになります。

<DIV>
 <ul>
  <li>CC(fr3.1)<br/> : AX(en1.1)</li>
  <li>(fr4.1)<br/> : AX(en1.1)</li>
  <li>AA(fr1.1)<br/> : BX(en2.1)</li>
  <li>CC(fr3.1)<br/> : BX(en2.1)</li>

  <li>DD(fr1.2)<br/> : (en1.2)</li>
  <li>EE(fr2.2)<br/> : FX(en6.2)</li>
  <li>FF(fr3.2)<br/> : (en3.2)</li>
  <li>GG(fr4.2)<br/> : DX(en4.2)</li>
  <li>HH(fr5.2)<br/> : EX(en5.2)</li>
 </ul>
</DIV>

「fr」で始まる数値データは、同じ行レベルの列に入れる必要があります。そのため、「en」で始まるデータは下の行に入る必要があります。ドットの後の数字は、テキスト データとそれに付随する括弧内の数字が、出力内の同じ <seg> 要素に属していることを意味します。各 <seg> からのデータは、個別のテーブルに配置する必要があります。たとえば、上記の入力には 2 つの別個のテーブルが必要です。色分けでは、2 つのテストを考慮する必要があります。1) 「fr」行の数値が、「en」行の下のセルの対応する値と同じ場合、両方のセルに背景色の黄色を割り当てる必要があります。 (#ffff00); 2) xml 入力の数値データにテキスト データが含まれていない場合、入力にテキスト値が含まれていない数値が入るセル

全体として、HTML 出力は次のようになります。

テーブル

ありがとう!

4

1 に答える 1

2

最初に行う必要があるのは、データを「seg」番号で「グループ化」することです。これは、この場合、ピリオドの後、最後の括弧の前の値です。XSLT 1.0 では、これはMuenchian グループ化と呼ばれる手法によって行われます。これを行うには、まずこの値でli要素をグループ化するキーを定義します。

<xsl:key name="type" match="li" use="substring-before(substring-after(text(), '.'), ')')" />

次に、関連する「seg」番号のグループで最初に発生するli要素を照合します。これは次のように行われます。

<xsl:template match="li">
   <xsl:variable name="seg" select="substring-before(substring-after(text(), '.'), ')')"/>
   <xsl:if test="generate-id() = generate-id(key('type', $seg)[1])">

これにより、2 つの異なる「セグメント」グループが得られます。

次に、グループごとに、最初に「fr」テキストのすべてのテキスト ノードを取得します (それらが常に最初に表示されると仮定します)。

<xsl:apply-templates select="key('type', $seg)/text()[1]">
   <xsl:with-param name="cellnumber" select="1"/>
</xsl:apply-templates>

これは、比較のために他の「セル」のテキストを取得するために使用されるため、セル番号も渡していることに注意してください。

そして、「en」テキストを取得するのも同様です

<xsl:apply-templates select="key('type', $seg)/text()[2]">
   <xsl:with-param name="cellnumber" select="2"/>
</xsl:apply-templates>

これらに一致するテンプレート内で、文字列操作を使用して必要な値を取得します (XSLT 2.0 では、正規表現の力を使用して単純化できます)。

最初の 2 文字 (たとえば、'CC' や 'AX' など) を取得するには、それらが存在する場合、次のようにします。

 <xsl:variable name="text" select="translate(substring-before(., '('), ' :', '')"/>

番号を取得するには、次のようにします (これは、「fr」または「en」しかないことを前提としています)。

<xsl:variable name="number" select="translate(substring-after(., '('), 'fren)', '')"/>

ここで、他のセルのテキストを取得するために、パラメーターとして渡されたcellnumberを利用できます。

<xsl:variable name="othercell" select="../text()[3 - $cellnumber]"/>

次に、同様の方法で数値を抽出し、比較で使用して色を取得できます。

  <xsl:variable name="colour">
     <xsl:choose>
        <xsl:when test="$text = ''">FF0000</xsl:when>
        <xsl:when test="$number = $othernumber">FFFFFF</xsl:when>
        <xsl:otherwise>FFFF00</xsl:otherwise>
     </xsl:choose>
  </xsl:variable>

この XSLT を試してください:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:output method="xml" indent="yes"/>

   <xsl:key name="type" match="li" use="substring-before(substring-after(text(), '.'), ')')"/>

   <xsl:template match="/">
      <xsl:apply-templates select="//li"/>
   </xsl:template>

   <xsl:template match="li">
      <xsl:variable name="seg" select="substring-before(substring-after(text(), '.'), ')')"/>
      <xsl:if test="generate-id() = generate-id(key('type', $seg)[1])">
         <h1 id="{$seg}">
            <xsl:value-of select="$seg"/>
         </h1>
         <table>
         <tr>
            <td>fr</td>
            <xsl:apply-templates select="key('type', $seg)/text()[1]">
               <xsl:with-param name="cellnumber" select="1"/>
            </xsl:apply-templates>
         </tr>
         <tr>
            <td>en</td>
            <xsl:apply-templates select="key('type', $seg)/text()[2]">
               <xsl:with-param name="cellnumber" select="2"/>
            </xsl:apply-templates>
         </tr>
         </table>
      </xsl:if>
   </xsl:template>

   <xsl:template match="text()">
      <xsl:param name="cellnumber"/>

      <xsl:variable name="text" select="translate(substring-before(., '('), ' :', '')"/>
      <xsl:variable name="number" select="translate(substring-after(., '('), 'fren)', '')"/>

      <xsl:variable name="othercell" select="../text()[3 - $cellnumber]"/>
      <xsl:variable name="othernumber" select="translate(substring-after($othercell, '('), 'fren)', '')"/>
      <xsl:variable name="colour">
         <xsl:choose>
            <xsl:when test="$text = ''">FF0000</xsl:when>
            <xsl:when test="$number = $othernumber">FFFFFF</xsl:when>
            <xsl:otherwise>FFFF00</xsl:otherwise>
         </xsl:choose>
      </xsl:variable>
      <td style="background-color:#{$colour}">
         <xsl:value-of select="$number"/>
      </td>
   </xsl:template>
</xsl:stylesheet>

これにより、次のように出力されます

<h1 id="1">1</h1>
<table>
    <tr>
        <td>fr</td>
        <td style="background-color:#FFFF00">3.1</td>
        <td style="background-color:#FF0000">4.1</td>
        <td style="background-color:#FFFF00">1.1</td>
        <td style="background-color:#FFFF00">3.1</td>
    </tr>
    <tr>
        <td>en</td>
        <td style="background-color:#FFFF00">1.1</td>
        <td style="background-color:#FFFF00">1.1</td>
        <td style="background-color:#FFFF00">2.1</td>
        <td style="background-color:#FFFF00">2.1</td>
    </tr>
</table>
<h1 id="2">2</h1>
<table>
    <tr>
        <td>fr</td>
        <td style="background-color:#FFFFFF">1.2</td>
        <td style="background-color:#FFFF00">2.2</td>
        <td style="background-color:#FFFFFF">3.2</td>
        <td style="background-color:#FFFFFF">4.2</td>
        <td style="background-color:#FFFFFF">5.2</td>
    </tr>
    <tr>
        <td>en</td>
        <td style="background-color:#FF0000">1.2</td>
        <td style="background-color:#FFFF00">6.2</td>
        <td style="background-color:#FF0000">3.2</td>
        <td style="background-color:#FFFFFF">4.2</td>
        <td style="background-color:#FFFFFF">5.2</td>
    </tr>
</table>

これは図と「完全に」一致しませんが、図は、色付けがどのように機能するかを説明した方法とは完全に一致していません。

于 2013-07-17T22:29:16.623 に答える