0

私は XSLT を初めて使用し、この問題を解決するのに苦労しています。

入力は XML Excel ドキュメントから取得され、次の形式になります。

<Row>
  <Cell><Data ss:Type="String">ToE.3</Data></Cell>
  <Cell ss:Index="15"><Data ss:Type="String">Maintain</Data></Cell>
  <Cell><Data ss:Type="Number">3</Data></Cell>
  <Cell><Data ss:Type="String">Other</Data></Cell>
  <Cell ss:Index="131"><Data ss:Type="String">Windows 2003</Data></Cell>
  <Cell><Data >Microsoft SQL Server 2005</Data></Cell>
</Row>
..more rows (note the excel sheet has 132 columns)

これを標準のテキスト ファイルに変換する必要があります。たとえば、(右側の列で) separator のようなものです。

Col1  Col2 Col3 ..To.. Col15    Col16 ..To.. Col131
ToE.3                 Maintain 3              Windows 2003

問題は、Index 属性でスキップされる空の行の値を挿入する方法です。

空のインデックス処理のない変換は次のようになります。

<xsl:for-each select="Row">
    <xsl:for-each select="Cell/Data">
        <xsl:value-of select="current()"/>
        <xsl:text>\</xsl:text>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
</xsl:for-each>

いくつかの助けが温かく感謝されます

4

2 に答える 2

1

ご覧のとおり、Excelはデータが表示されない列をスキップし、後続の空白でない列にss:Index属性を提供するため、これは注意が必要です。「欠落している」セルの位置を自分で再構築する必要があります。つまり、例で「15」や「131」などの元の列の位置を保持したい場合は、空白を挿入します。

上記のInfantProgrammerに同意しますが、上記の「CopyData」テンプレートにロジックを追加して、(a)欠落しているセルの数を決定し、(b)再帰的な名前付きテンプレートを呼び出して出力に書き込むことをお勧めします。

<xsl:template name="WriteBlanks">
   <xsl:param name="Count" select="0"/>
   <xsl:if test="Count &gt; 0">
     <xsl:value-of select="'\'"/>
      <xsl:call-template name="WriteBlanks">
         <xsl:with-param name="Count" select="$Count - 1"/>
      </xsl:call-template>
   </xsl:if>
</xsl:template>

列ヘッダーの最初の行を生成するのと同様のことを行うことができます。

列区切り文字としてバックスラッシュ文字を書き込む必要があるという単純さを考えると、それらの長い文字列を作成し、XPathで必要な数を切り落とすという、より簡潔なアプローチが実現substring()できる可能性があります。ただし、再帰テンプレートは、より複雑な出力に適している場合があります。

于 2012-11-28T13:32:47.787 に答える
1

step1: 出力形式、つまり「xml」ではなく「text」を宣言する必要があります。

step2: 追加の空白を取り除く必要があります。element='*' で Strip-space を使用してください。これは「すべて」を意味します!

step3: 最初にヘッダー行、つまり col1、col2 などを書き込む必要があります。
そのため、テンプレート マッチを使用して、XML の最初の要素行を選択します。すべての行の列数が同じであると仮定すると、"COL+ NUMBER" ..column numbers = no of cells最初の行にあります。

step4:セルが最後にある場合は、「文字を入力」を挿入します..

step5: ジェネリック関数を呼び出す

step6: 一般的な機能の説明: この機能は、 で区切られた各セルの下にデータをコピーします\。最初の行についてのみ、手動で呼び出します。それ以外の場合は、テンプレート マッチが処理します。

コードは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text"/>
  <xsl:strip-space elements="*"/>

  <xsl:template name="Header" match="Row[not(preceding-sibling::Row)]">
    <xsl:for-each select="Cell">
      <xsl:value-of select="'Col'"/>
      <xsl:value-of select="position()"/>
      <xsl:if test="position()!=last()">
        <xsl:value-of select="'\'"/>
      </xsl:if>
     </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
    <xsl:call-template name="CopyData"/>
  </xsl:template>

  <xsl:template name="CopyData" match="Row">
    <xsl:for-each select="Cell">
      <xsl:for-each select="Data">
        <xsl:apply-templates select="."/>
      </xsl:for-each>
      <xsl:if test="position()!=last()">
        <xsl:value-of select="'\'"/>
      </xsl:if>
    </xsl:for-each>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

対応する出力例:

Col1\Col2\Col3\Col4\Col5\Col6
ToE.3\Maintain\3\Other\Windows 2003\Microsoft SQL Server 2005
ToE.3\Maintain\3\Other\Windows 2003\Microsoft SQL Server 2005
于 2012-11-28T12:22:04.447 に答える