2
<?xml version="1.0" encoding="utf-8"?>
<Report p1:schemaLocation="Customer details  http://reportserver?%2fCustomer details&amp;rs%3aFormat=XML&amp;rc%3aSchema=True" Name="Customer details" xmlns:p1="http://www.w3.org/2001/XMLSchema-instance" xmlns="Customer details">
  <table2>
   <Detail_Collection>
         <Detail Col1="aaa" col1_SeqID="2"  col1_Include="1"
                 Col2="aaa" col2_SeqID="1"  col2_Include="1"
                 Col3="aaa" col3_SeqID=""  col3_Include="0"
                 Col4="aaa" col4_SeqID="4"  col4_Include="1"
                 Col5="aaa" col5_SeqID=""  col5_Include="0"
                 ... ... ...
                 ... ... ...
                 ... ... ...
                 Col50="aaa" col50_SeqID="3"  col50_Include="1"
                 />
   <Detail_Collection>
</table2>
</Report>

上記の xml は、RDL ファイル用に SSRS によって生成されます。上記のxmlファイルをXSLT(カスタマイズフォーマット)を使ってCSV形式に変換したいです。RDL ファイル (SSRS レポート) は 50 列の非常にシンプルで、ユーザー インターフェイスでのユーザーの選択に応じてすべての列のデータが表示されます。ユーザー インターフェイスでは、50 列すべてのパラメーターを選択できます (つまり、列の順序を選択したり、特定の列をレポートに含めるかどうかを選択したり、フォント スタイルなどを選択したりできます...)。前述のように、各列には 2 つの主な機能があります。つまり、選択に基づいて並べ替えたり、並べ替えたりすることができます。

たとえば、上記の xml 形式のレポート出力から、50 列すべてが xml 形式に存在することがわかりますが、通常はレポートに表示されない余分なフィールドも含めています。

col1 はレポートに含まれ、csv ファイルの 2 番目の列として順序付けられます (seqID)。col2 もレポートに含まれており、csv ファイルの最初の列として並べられています。col3 はレポートに含まれておらず、注文の選択も空であるため、csv ファイルには含まれていません。... ... 同様に、col50 はレポートに含まれていますが、csv ファイルでは 3 列目に配置されています。

ここでの私の主な課題は、「CSV」の xslt ファイルを作成し、ユーザーごとに選択される順序選択に列を配置することです。

変換後の CSV ファイルの出力は次のようになります。

Col2    Col1    Col50   Col4
 ...  ...       ...     ....

この種の xsl ファイルを作成するための良いアイデアは大歓迎です。私の質問を理解し、この点で私を助けようとしてくれてありがとう。

4

1 に答える 1

1

I. この XSLT 1.0 変換:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:c="Customer details">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="c:Detail">
     <xsl:apply-templates select=
      "@*[substring(name(), string-length(name())-5)
         = '_SeqID'
        and
          number(.) = number(.)
          ]
     ">
      <xsl:sort data-type="number"/>
     </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="@*">
  <xsl:if test="not(position()=1)">,</xsl:if>
  <xsl:value-of select=
    "../@*
       [name()
       =
        concat('Col',substring-before(substring(name(current()),4),'_'))
        ]"/>
 </xsl:template>
</xsl:stylesheet>

この XML ドキュメント(整形式で明確に作成された、提供されたもの)に適用すると、次のようになります。

<Report
p1:schemaLocation="Customer details  http://reportserver?%2fCustomer details&amp;rs%3aFormat=XML&amp;rc%3aSchema=True"
Name="Customer details"
xmlns:p1="http://www.w3.org/2001/XMLSchema-instance"
xmlns="Customer details">
    <table2>
        <Detail_Collection>
            <Detail Col1="aaa1" col1_SeqID="2"  col1_Include="1"
            Col2="aaa2" col2_SeqID="1"  col2_Include="1"
            Col3="aaa3" col3_SeqID=""  col3_Include="0"
            Col4="aaa4" col4_SeqID="4"  col4_Include="1"
            Col5="aaa5" col5_SeqID=""  col5_Include="0"
            Col50="aaa50" col50_SeqID="3"  col50_Include="1"
            />
        </Detail_Collection>
    </table2>
</Report>

必要な正しい結果が生成されます

aaa2,aaa1,aaa50,aaa4

説明:

  1. XPath 1.0 式を使用します。

__

substring($s1, string-length($s1) - string-length($s2) +1) = $s2

XPath 2.0 式と同等です。

ends-with($s1, $s2))

.2. <xsl:sort>substring()name()およびの適切な使用current()

.3. $s次の場合にのみ、文字列が数値にキャスト可能であるという事実を使用します。

__

number($s) = number($s)

Ⅱ.XSLT 2.0 ソリューション:

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:c="Customer details">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>    

 <xsl:template match="c:Detail">
         <xsl:apply-templates select=
          "@*[ends-with(name(),'_SeqID')
            and . castable as xs:integer]">
          <xsl:sort  select="xs:integer(.)"/>
         </xsl:apply-templates>
 </xsl:template>
 <xsl:template match="@*">
      <xsl:if test="not(position()=1)">,</xsl:if>
      <xsl:value-of select=
        "../@*
           [name()
           eq
            concat('Col',translate(name(current()),'col_SeqID',''))]"/>
 </xsl:template>
</xsl:stylesheet>

この変換を同じ XML ドキュメント (上記) に適用すると、同じ正しい結果が生成されます。

aaa2,aaa1,aaa50,aaa4

更新: @desi は、見出しも生成するように依頼しました。

以下は、これを行う更新された XSLT 1.0 変換です(示されているように、@desi は XSLT 1.0 のみの使用に制限されています)。

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:c="Customer details">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="c:Detail">

     <xsl:for-each select=
      "@*[substring(name(), string-length(name())-5)
         = '_SeqID'
        and
          number(.) = number(.)
          ]
        ">
        <xsl:sort data-type="number"/>

       <xsl:value-of select=
       "concat('Col',
               substring-before(substring(name(current()),4),
                                '_')
               )
       "/>

          <xsl:text>&#9;</xsl:text>
     </xsl:for-each>
     <xsl:text>&#10;</xsl:text>

     <xsl:apply-templates select=
      "@*[substring(name(), string-length(name())-5)
         = '_SeqID'
        and
          number(.) = number(.)
          ]
     ">
      <xsl:sort data-type="number"/>
     </xsl:apply-templates>
 </xsl:template>

 <xsl:template match="@*">
  <xsl:if test="not(position()=1)">,</xsl:if>
  <xsl:value-of select=
    "../@*
       [name()
       =
        concat('Col',substring-before(substring(name(current()),4),'_'))
        ]"/>
 </xsl:template>
</xsl:stylesheet>

この変換が同じ XML ドキュメント (上記) に適用されると、必要な正しい結果が生成されます。

Col2    Col1    Col50   Col4    
aaa2,aaa1,aaa50,aaa4
于 2011-09-25T03:23:05.227 に答える