XSLT:多个xml输入和匹配值

时间:2015-02-13 16:47:44

标签: xml xslt saxon

我使用saxon:我有xhtml,实际上是一个带有这样的令牌的表:

    <?xml version="1.0" encoding="windows-1252"?>

<!DOCTYPE html
   PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title></title>
    <meta name="GENERATOR" content="OpenOffice.org 3.3  (Win32)" />
    <meta name="CREATED" content="0;0" />
    <meta name="CHANGED" content="20150212;12040469" />
    <style type="text/css" xml:space="preserve">

        BODY,DIV,TABLE,THEAD,TBODY,TFOOT,TR,TH,TD,P { font-family:"Arial"; font-size:x-small }

    </style>
  </head>
  <body text="#000000">
    <table frame="void" cellspacing="0" rules="none" border="0">
      <colgroup>
        <col width="78" />
        <col width="379" />
        <col width="370" />
        <col width="165" />
        <col width="165" />
        <col width="120" />
        <col width="135" />
        <col width="135" />
      </colgroup><tbody>
        <tr>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="78" height="82" align="center">
            <b>CODE </b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="379" align="center">
            <b>DISPLAY NAME </b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="370" align="center">
            <b><font color="#000000">
            2013 </font></b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="165" align="center">
            <b>TYPE</b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="165" align="center">
            <b>2013 FORECAST</b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="120" align="center">
            <b>2014 FORECAST<br /></b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="135" align="center">
            <b>2015 FORECAST</b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="135" align="center">
            <b>2016 FORECAST</b>
          </td>
        </tr>
        <tr>
          <td style="border-top: 1px solid #000000; border-left: 1px solid #000000" height="17" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
          </td>
          <td style="border-top: 1px solid #000000; border-right: 1px solid #000000" align="left">
            <br />
          </td>
        </tr>
        <tr>
          <td style="border-left: 1px solid #000000" height="17" align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td style="border-right: 1px solid #000000" align="left">
            <br />
          </td>
        </tr>
        <tr>
          <td style="border-left: 1px solid #000000" height="17" align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td style="border-right: 1px solid #000000" align="left">
            <br />
          </td>
        </tr>
        <tr>
          <td style="border-left: 1px solid #000000" height="17" align="left">
            2 001
          </td>
          <td align="left">
            SOME TEXT TO DISPLAY 1</td>
          <td align="left">

            <br />
          </td>
          <td align="left">
            some type 1</td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td style="border-right: 1px solid #000000" align="left">
            <br />
          </td>
        </tr>
        <tr>
          <td style="border-left: 1px solid #000000" height="17" align="left">
            <br />
          </td>
          <td align="left">
            SOME TEXT TO DISPLAY 2</td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td style="border-right: 1px solid #000000" align="left">
            <br />
          </td>
        </tr>
        <tr>
          <td style="border-left: 1px solid #000000" height="17" align="left">
            2 002
          </td>
          <td align="left">
            SOME TEXT TO DISPLAY 3</td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            some type 3</td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td style="border-right: 1px solid #000000" align="left">
            <br />
          </td>
        </tr>
      </tbody>
    </table>
    <!-- 
      ************************************************************************** -->
  </body>
</html>

在这个xhtml中,我有一个td元素的代码,如:2 001,2 002。

现在我有一个xml文件,允许您映射这样的数据:

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<certificati>
    <certificato anno="2014" codiceEnte="#CODICE_ENTE#"
        tipoCertificato="P" tipoValuta="E">

        <elemento>
            <colonne quadro="02" voce="001">
                <colonna num="1">123</colonna>
                <colonna num="2">456</colonna>
                <colonna num="3">789</colonna>
                <colonna num="4">10112</colonna>
                <colonna num="5">1312</colonna>
            </colonne>
            <colonne quadro="02" voce="002">
                <colonna num="1">2123</colonna>
                <colonna num="2">3456</colonna>
                <colonna num="3">567</colonna>
                <colonna num="4">876</colonna>
                <colonna num="5">8765</colonna>
            </colonne>

        </elemento> 
    </certificato>
</certificati>

输出文件必须是xhtml,其值与xml文件中的值匹配:对于匹配值,您必须使用此键,例如:<colonne quadro="02" voce="001">,用于xhtml中TD元素中的2 001,并填充其他值

输出档案必须是:

    <?xml version="1.0" encoding="windows-1252"?>

<!DOCTYPE html
   PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" >

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title></title>
    <meta name="GENERATOR" content="OpenOffice.org 3.3  (Win32)" />
    <meta name="CREATED" content="0;0" />
    <meta name="CHANGED" content="20150212;12040469" />
    <style type="text/css" xml:space="preserve">

        BODY,DIV,TABLE,THEAD,TBODY,TFOOT,TR,TH,TD,P { font-family:"Arial"; font-size:x-small }

    </style>
  </head>
  <body text="#000000">
    <table frame="void" cellspacing="0" rules="none" border="0">
      <colgroup>
        <col width="78" />
        <col width="379" />
        <col width="370" />
        <col width="165" />
        <col width="165" />
        <col width="120" />
        <col width="135" />
        <col width="135" />
      </colgroup><tbody>
        <tr>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="78" height="82" align="center">
            <b>CODE </b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="379" align="center">
            <b>DISPLAY NAME </b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="370" align="center">
            <b><font color="#000000">
            2013 </font></b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="165" align="center">
            <b>TYPE</b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="165" align="center">
            <b>2013 FORECAST</b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="120" align="center">
            <b>2014 FORECAST<br /></b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="135" align="center">
            <b>2015 FORECAST</b>
          </td>
          <td style="border-top: 1px solid #000000; border-bottom: 1px solid #000000; border-left: 1px solid #000000; border-right: 1px solid #000000" width="135" align="center">
            <b>2016 FORECAST</b>
          </td>
        </tr>
        <tr>
          <td style="border-top: 1px solid #000000; border-left: 1px solid #000000" height="17" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
            <br />
          </td>
          <td style="border-top: 1px solid #000000" align="left">
          </td>
          <td style="border-top: 1px solid #000000; border-right: 1px solid #000000" align="left">
            <br />
          </td>
        </tr>
        <tr>
          <td style="border-left: 1px solid #000000" height="17" align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td style="border-right: 1px solid #000000" align="left">
            <br />
          </td>
        </tr>
        <tr>
          <td style="border-left: 1px solid #000000" height="17" align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td style="border-right: 1px solid #000000" align="left">
            <br />
          </td>
        </tr>
        <tr>
          <td style="border-left: 1px solid #000000" height="17" align="left">2 001</td>
          <td align="left">
            SOME TEXT TO DISPLAY 1</td>
          <td align="left">

            <br />
            123
          </td>
          <td align="left">
            some type 1</td>
          <td align="left">
            <br />
            456
          </td>
          <td align="left">
            <br />
            789
          </td>
          <td align="left">
            <br />
            10112
          </td>
          <td style="border-right: 1px solid #000000" align="left">

            <br />
            1312
          </td>
        </tr>
        <tr>
          <td style="border-left: 1px solid #000000" height="17" align="left">
            <br />
          </td>
          <td align="left">
            SOME TEXT TO DISPLAY 2</td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td align="left">
            <br />
          </td>
          <td style="border-right: 1px solid #000000" align="left">
            <br />
          </td>
        </tr>
        <tr>
          <td style="border-left: 1px solid #000000" height="17" align="left">
            2 002
          </td>
          <td align="left">
            SOME TEXT TO DISPLAY 3</td>
          <td align="left">
            <br />
            2123
          </td>
          <td align="left">
            some type 3</td>
          <td align="left">
            <br />
            3456
          </td>
          <td align="left">
            <br />
            567
          </td>
          <td align="left">
            <br />
            876
          </td>
          <td style="border-right: 1px solid #000000" align="left">
            <br />
            8765
          </td>
        </tr>
      </tbody>
    </table>
    <!-- 
      ************************************************************************** -->
  </body>
</html>

问题是:如何使用单个样式表进行此输出?

1 个答案:

答案 0 :(得分:0)

有一个文档在XHTML命名空间中有元素而另一个文档中没有命名空间中的元素,这有点棘手。此外,XHTML文档中的数字格式与其他文档中的数字格式不同。为了弥补这一点,我必须使用string(xs:integer(...))转换。

这是我的建议:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:xhtml="http://www.w3.org/1999/xhtml"
  exclude-result-prefixes="xs xhtml"
  xpath-default-namespace="http://www.w3.org/1999/xhtml">

<xsl:param name="doc2-url" as="xs:string" select="'test2015021302.xml'"/>
<xsl:param name="doc2" as="document-node()" select="doc($doc2-url)"/>

<xsl:key name="col"
         xpath-default-namespace=""
         match="elemento/colonne"
         use="string-join(for $att in (@quadro, @voce) return string(xs:integer($att)), '|')"/>

<xsl:output
  method="xhtml"
  doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
  doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* , node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="tr[key('col', string-join(for $s in tokenize(td[1], '\s+')[normalize-space()] return string(xs:integer($s)), '|'), $doc2)]/td[not(text()[normalize-space()])]">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
    <xsl:copy-of xpath-default-namespace="" select="key('col', string-join(for $s in tokenize(../xhtml:td[1], '\s+')[normalize-space()] return string(xs:integer($s)), '|'), $doc2)/colonna[position() = count(current()/preceding-sibling::xhtml:td[not(text()[normalize-space()])]) + 1]/node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>