【问题标题】:Transform existing XML for Excel with XSLT使用 XSLT 为 Excel 转换现有 XML
【发布时间】:2012-11-02 08:42:26
【问题描述】:

我需要更改现有的 xml 以便从中制作一个 excel 表格。

我需要更改的xml:

<rows>
  <row>
    <cell image="blank.gif">Row1</cell>
    <cell>1</cell>
    <cell>2</cell>
    <cell>3</cell>
    <cell>4</cell>
    <cell>5</cell>
    <cell>6</cell>
    <cell>7</cell>
    <row>
      <cell image="blank.gif">Row1_1</cell>
      <cell>8</cell>
      <cell>9</cell>
      <cell>10</cell>
      <cell>11</cell>
      <cell>12</cell>
      <cell>13</cell>
      <cell>14</cell>
    </row>
    <row>
      <cell image="blank.gif">Row1_2</cell>
      <cell>15</cell>
      <cell>16</cell>
      <cell>17</cell>
      <cell>18</cell>
      <cell>19</cell>
      <cell>20</cell>
      <cell>21</cell>
    </row>
  </row>
  <row>
    <cell image="blank.gif">Row2</cell>
    <cell>22</cell>
    <cell>23</cell>
    <cell>24</cell>
    <cell>25</cell>
    <cell>26</cell>
    <cell>27</cell>
    <cell>28</cell>
  </row>
</rows>

我当前的 XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>



  <xsl:template match="rows">
    <xsl:element name="sheetData">
      <xsl:apply-templates select="row"></xsl:apply-templates>
    </xsl:element>
  </xsl:template>



  <xsl:template match="row">
    <xsl:variable name="rowID">
      <xsl:number value="position()" format="1"/>
    </xsl:variable>
    <xsl:element name="row">
      <xsl:attribute name="r">
        <xsl:value-of select="$rowID"/>
      </xsl:attribute>



      <xsl:for-each select="*">
        <xsl:element name="c">
          <xsl:variable name="colID">
            <xsl:number value="position()" format="A"/>
          </xsl:variable>
          <xsl:attribute name="r">
            <xsl:value-of  select="concat(string($colID),string($rowID))"/>
          </xsl:attribute>
          <xsl:attribute name="t">
            <xsl:text>inlineStr</xsl:text>
          </xsl:attribute>
          <xsl:element name="is">
            <xsl:element name="t">
              <xsl:value-of select="."/>
            </xsl:element>
          </xsl:element>
        </xsl:element>
      </xsl:for-each>

    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

我的转换输出:

<sheetData>
 <row r="1">
  <c r="A1" t="inlineStr">
      <is>
      <t>Row1</t> 
      </is>
  </c>
  <c r="B1" t="inlineStr">
      <is>
      <t>1</t> 
      </is>
  </c>
  <c r="C1" t="inlineStr">
      <is>
      <t>2</t> 
      </is>
  </c>
  <c r="D1" t="inlineStr">
      <is>
      <t>3</t> 
      </is>
  </c>
  <c r="E1" t="inlineStr">
      <is>
      <t>4</t> 
      </is>
  </c>
  <c r="F1" t="inlineStr">
      <is>
      <t>5</t> 
      </is>
  </c>
  <c r="G1" t="inlineStr">
      <is>
      <t>6</t> 
      </is>
  </c>
  <c r="H1" t="inlineStr">
      <is>
      <t>7</t> 
      </is>
  </c>
  <c r="I1" t="inlineStr">
      <is>
      <t>Row1_1891011121314</t> 
      </is>
  </c>
  <c r="J1" t="inlineStr">
      <is>
      <t>Row1_215161718192021</t> 
      </is>
  </c>
  </row>
  <row r="2">
  <c r="A2" t="inlineStr">
      <is>
      <t>Row2</t> 
      </is>
  </c>
  <c r="B2" t="inlineStr">
      <is>
      <t>22</t> 
      </is>
  </c>
  <c r="C2" t="inlineStr">
      <is>
      <t>23</t> 
      </is>
  </c>
  <c r="D2" t="inlineStr">
      <is>
      <t>24</t> 
      </is>
  </c>
  <c r="E2" t="inlineStr">
      <is>
      <t>25</t> 
      </is>
  </c>
  <c r="F2" t="inlineStr">
      <is>
      <t>26</t> 
      </is>
  </c>
  <c r="G2" t="inlineStr">
      <is>
      <t>27</t> 
      </is>
  </c>
  <c r="H2" t="inlineStr">
      <is>
      <t>28</t> 
      </is>
  </c>
 </row>
</sheetData>

以及生成的 excel 文档的截图:

所以我的问题是我需要像 Row1 和 Row2 一样显示它们的嵌套行

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    我认为您的意思是您希望输入 XML 中的每个 row 在输出中都有一个单独的行,即使行元素是嵌套的。

    首先,你需要替换这一行

    <xsl:for-each select="*">
    

    有了这个……

    <xsl:for-each select="cell">
    

    这样可以保证当前行只输出cell元素,嵌套的row元素不会被处理。

    然后,在您创建了仅包含 cell 元素的 row 元素后,您可以查找嵌套的 row 元素来输出这些

    <row>
       <!-- Process Cells -->
    </row>
    <xsl:apply-templates select="row"/>
    

    注意没有真正需要使用xsl:element来输出静态命名元素,直接写出元素即可。您的代码也可以通过使用属性值模板来创建属性来整理,而不是使用 xsl:attribute

    试试下面的 XSLT:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       <xsl:output method="xml" indent="yes"/>
    
       <xsl:template match="rows">
          <sheetData>
             <xsl:apply-templates select="row"/>
          </sheetData>
       </xsl:template>
    
       <xsl:template match="row">
          <xsl:variable name="rowID">
             <xsl:number level="any" format="1"/>
          </xsl:variable>
          <row r="{$rowID}">
             <xsl:for-each select="cell">
                <xsl:variable name="colID">
                   <xsl:number value="position()" format="A"/>
                </xsl:variable>
                <c t="inlineStr" r="{string($colID)}{string($rowID)}">
                   <is>
                      <t>
                         <xsl:value-of select="."/>
                      </t>
                   </is>
                </c>
             </xsl:for-each>
          </row>
          <xsl:apply-templates select="row"/>
       </xsl:template>
    </xsl:stylesheet>
    

    当应用于您的 XML 时,将输出以下内容

    <sheetData>
       <row r="1">
          <c t="inlineStr" r="A1">
             <is>
                <t>Row1</t>
             </is>
          </c>
          <c t="inlineStr" r="B1">
             <is>
                <t>1</t>
             </is>
          </c>
          <c t="inlineStr" r="C1">
             <is>
                <t>2</t>
             </is>
          </c>
          <c t="inlineStr" r="D1">
             <is>
                <t>3</t>
             </is>
          </c>
          <c t="inlineStr" r="E1">
             <is>
                <t>4</t>
             </is>
          </c>
          <c t="inlineStr" r="F1">
             <is>
                <t>5</t>
             </is>
          </c>
          <c t="inlineStr" r="G1">
             <is>
                <t>6</t>
             </is>
          </c>
          <c t="inlineStr" r="H1">
             <is>
                <t>7</t>
             </is>
          </c>
       </row>
       <row r="2">
          <c t="inlineStr" r="A2">
             <is>
                <t>Row1_1</t>
             </is>
          </c>
          <c t="inlineStr" r="B2">
             <is>
                <t>8</t>
             </is>
          </c>
          <c t="inlineStr" r="C2">
             <is>
                <t>9</t>
             </is>
          </c>
          <c t="inlineStr" r="D2">
             <is>
                <t>10</t>
             </is>
          </c>
          <c t="inlineStr" r="E2">
             <is>
                <t>11</t>
             </is>
          </c>
          <c t="inlineStr" r="F2">
             <is>
                <t>12</t>
             </is>
          </c>
          <c t="inlineStr" r="G2">
             <is>
                <t>13</t>
             </is>
          </c>
          <c t="inlineStr" r="H2">
             <is>
                <t>14</t>
             </is>
          </c>
       </row>
       <row r="3">
          <c t="inlineStr" r="A3">
             <is>
                <t>Row1_2</t>
             </is>
          </c>
          <c t="inlineStr" r="B3">
             <is>
                <t>15</t>
             </is>
          </c>
          <c t="inlineStr" r="C3">
             <is>
                <t>16</t>
             </is>
          </c>
          <c t="inlineStr" r="D3">
             <is>
                <t>17</t>
             </is>
          </c>
          <c t="inlineStr" r="E3">
             <is>
                <t>18</t>
             </is>
          </c>
          <c t="inlineStr" r="F3">
             <is>
                <t>19</t>
             </is>
          </c>
          <c t="inlineStr" r="G3">
             <is>
                <t>20</t>
             </is>
          </c>
          <c t="inlineStr" r="H3">
             <is>
                <t>21</t>
             </is>
          </c>
       </row>
       <row r="4">
          <c t="inlineStr" r="A4">
             <is>
                <t>Row2</t>
             </is>
          </c>
          <c t="inlineStr" r="B4">
             <is>
                <t>22</t>
             </is>
          </c>
          <c t="inlineStr" r="C4">
             <is>
                <t>23</t>
             </is>
          </c>
          <c t="inlineStr" r="D4">
             <is>
                <t>24</t>
             </is>
          </c>
          <c t="inlineStr" r="E4">
             <is>
                <t>25</t>
             </is>
          </c>
          <c t="inlineStr" r="F4">
             <is>
                <t>26</t>
             </is>
          </c>
          <c t="inlineStr" r="G4">
             <is>
                <t>27</t>
             </is>
          </c>
          <c t="inlineStr" r="H4">
             <is>
                <t>28</t>
             </is>
          </c>
       </row>
    </sheetData>
    

    【讨论】:

    • 行 r 属性存在问题,它们需要不同。您的输出显示具有相同 r 的行,而 excel 文档无法读取这些行。
    • 好点!我已经调整了我的答案,以便现在根据需要将行编号为 1 到 4。
    【解决方案2】:

    您可以做的另一件事是按原样导入 XML。

    1. 切换到 XML 映射(开发工具,xml 源,[xml 映射应该在右侧打开])
    2. 全部删除
    3. 然后你可以用右键选择“添加”将数据输入到 Excel 工作表中

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多