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(), '.'), ')')" />

然后,您将匹配组中首先出现的li元素,以获得它们的相关“seg”编号。这样做是这样的:

<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])">

这为您提供了两个不同的“seg”组。

对于每个组,您将首先获取“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 中,您可以使用正则表达式的强大功能来简化事情)

要获取前两个字母(例如“CC”或“AX”等),如果它们存在,您可以这样做

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

为了得到这个数字,你会这样做(这假设你只会有'fr'或'en')

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

现在,要获取另一个单元格中的文本,您可以使用作为参数传入的单元格编号

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