2

さまざまな種類のレポート用の XML ドキュメントを生成するレポート ジェネレータ ツールがあります。これらの XML ドキュメントには、実際のデータ (以下の XML ドキュメントの reporting:line) を記述するために使用される一連のフィールド (以下の XML ドキュメントの reporting:columns) があります。フィールドのリストは動的で、レポートの種類ごとに変化し続けるため、「フィールド」を使用してデータを csv ファイルに変換する一般的な XSL テンプレートを作成する方法。

私のサンプル XML ドキュメント:

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<reporting:root xmlns:reporting="http://www.something.net/reporting">

  <reporting:default0 reporting:type="Portfolio">
    <reporting:header>      
      <reporting:configuration>
        <reporting:columns>
          <reporting:column reporting:group="instrument" reporting:name="Ident" reporting:tag="ident" reporting:type="int"/>
          <reporting:column reporting:group="prices" reporting:name="Last (Time)" reporting:tag="lastTime" reporting:type="string"/>
          <reporting:column reporting:group="noGroup" reporting:name="RIC" reporting:tag="ric" reporting:type="string"/>
          <reporting:column reporting:group="instrument" reporting:name="Reference" reporting:tag="reference" reporting:type="string"/>
         <reporting:column reporting:group="result" reporting:name="Currency" reporting:tag="currency" reporting:type="string"/>          
        </reporting:columns>
     </reporting:configuration>      
    </reporting:header>
    <reporting:window reporting:Id="36674" reporting:level="0" reporting:name="MY_PORTFOLIO" reporting:parentId="11991">
      <reporting:line reporting:Id="67520135" reporting:level="1" reporting:name="INTERNATIONAL BUSINESS MACHINES CORP" reporting:parentId="36674" reporting:positionType="0">
        <reporting:ident>643633</reporting:ident>        
        <reporting:reference>IBM.USD</reporting:reference>
        <reporting:currency>USD</reporting:currency>        
      </reporting:line>
     <reporting:line reporting:Id="67520179" reporting:level="1" reporting:name="GENERAL ELECTRIC CO" reporting:parentId="36674" reporting:positionType="0">
        <reporting:ident>643635</reporting:ident>
        <reporting:ric>GE.N</reporting:ric>
        <reporting:reference>GE.USD</reporting:reference>
        <reporting:currency>USD</reporting:currency>        
     </reporting:line>
    </reporting:window>
  </reporting:default0>
</reporting:root>

次のようにフォーマットされた出力を確認する必要があります。

ident,lastTime,ric,reference,currency
643633,,,IBM.USD,USD
643635,,GE.N,GE.USD,USD

色々やったけど中途半端。がフィールドの「動的」リストを処理し、実際のデータを説明するタグとして使用する方法を見つけることができませんでした。

誰か助けてくれませんか?

ありがとう。

4

4 に答える 4

1

XSLT でこれに取り組むにはさまざまな方法がありますが、最もエレガントで維持しやすい方法は、指定されたソース ドキュメントを処理し、XSLT スタイルシートを出力して実際のレポートを行うスタイルシートを作成することだと思います。このアプローチが多くのプロジェクトで非常にうまく使用されているのを見てきました。

于 2012-05-08T20:08:45.787 に答える
0

この短くて単純な変換:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:r="http://www.something.net/reporting">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vColNames" select="/*/*/r:header/*/*/*/@r:tag"/>

 <xsl:template match="/">
  <xsl:for-each select="$vColNames">
   <xsl:value-of select="concat(., ',')"/>
  </xsl:for-each>
  <xsl:apply-templates/>
 </xsl:template>

 <xsl:template match="r:line">
  <xsl:variable name="vThis" select="."/>
  <xsl:text>&#xA;</xsl:text>
  <xsl:for-each select="$vColNames">
    <xsl:if test="position() > 1">,</xsl:if>
    <xsl:apply-templates select="$vThis/*[local-name() = current()]"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

提供された XML ドキュメントで実行すると、次のようになります。

<reporting:root xmlns:reporting="http://www.something.net/reporting">

  <reporting:default0 reporting:type="Portfolio">
    <reporting:header>
      <reporting:configuration>
        <reporting:columns>
          <reporting:column reporting:group="instrument" reporting:name="Ident" reporting:tag="ident" reporting:type="int"/>
          <reporting:column reporting:group="prices" reporting:name="Last (Time)" reporting:tag="lastTime" reporting:type="string"/>
          <reporting:column reporting:group="noGroup" reporting:name="RIC" reporting:tag="ric" reporting:type="string"/>
          <reporting:column reporting:group="instrument" reporting:name="Reference" reporting:tag="reference" reporting:type="string"/>
         <reporting:column reporting:group="result" reporting:name="Currency" reporting:tag="currency" reporting:type="string"/>
        </reporting:columns>
     </reporting:configuration>
    </reporting:header>
    <reporting:window reporting:Id="36674" reporting:level="0" reporting:name="MY_PORTFOLIO" reporting:parentId="11991">
      <reporting:line reporting:Id="67520135" reporting:level="1" reporting:name="INTERNATIONAL BUSINESS MACHINES CORP" reporting:parentId="36674" reporting:positionType="0">
        <reporting:ident>643633</reporting:ident>
        <reporting:reference>IBM.USD</reporting:reference>
        <reporting:currency>USD</reporting:currency>
      </reporting:line>
     <reporting:line reporting:Id="67520179" reporting:level="1" reporting:name="GENERAL ELECTRIC CO" reporting:parentId="36674" reporting:positionType="0">
        <reporting:ident>643635</reporting:ident>
        <reporting:ric>GE.N</reporting:ric>
        <reporting:reference>GE.USD</reporting:reference>
        <reporting:currency>USD</reporting:currency>
     </reporting:line>
    </reporting:window>
  </reporting:default0>
</reporting:root>

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

ident,lastTime,ric,reference,currency,
643633,,,IBM.USD,USD
643635,,GE.N,GE.USD,USD
于 2012-05-09T13:14:13.173 に答える
0

試す

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:r="http://www.something.net/reporting">
    <xsl:output method="text" version="1.0"/>
    <xsl:template match="/">
        <xsl:for-each select="/r:root/r:default0/r:header/r:configuration/r:columns/r:column">
            <xsl:value-of select="@r:tag"/>
            <xsl:if test="position() != last()">,</xsl:if>
        </xsl:for-each>
        <xsl:text>&#xA;</xsl:text>
        <xsl:for-each select="/r:root/r:default0/r:window/r:line">
            <xsl:variable name="POSITION" select="position()"/>
            <xsl:for-each select="//r:root/r:default0/r:header/r:configuration/r:columns/r:column">
                <xsl:variable name="TAGNAME" select="@r:tag"/><xsl:value-of select="//r:line[$POSITION]/*[local-name()=$TAGNAME]"/><xsl:if test="position() != last()">,</xsl:if>
            </xsl:for-each>
            <xsl:text>&#xA;</xsl:text>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

読みやすく (および入力しやすく) するために、名前空間のプレフィックスを短くしただけであることに注意してください。

于 2012-05-08T21:57:50.837 に答える
0
<xsl:output method="text"/>

<xsl:template match="/">

    <xsl:for-each select="/*:root/*:default0/*:header/*:configuration/*:columns/*:column">
        <xsl:value-of select="@reporting:tag"/>
        <xsl:text>,</xsl:text>
    </xsl:for-each>
    <xsl:for-each select="/*:root/*:default0/*:window/*:line">
        <xsl:variable name="theline"  select="."/>
        <xsl:text>&#x0a;</xsl:text>

        <xsl:for-each select="/*:root/*:default0/*:header/*:configuration/*:columns/*:column" >
            <xsl:variable name="oname"  select="@reporting:tag" />
              <xsl:value-of select="$theline/*[local-name()=$oname]" /><xsl:text>,</xsl:text>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

生産します:

ident、lastTime、ric、参照、通貨、

643633,,,IBM.USD,USD,

643635,,GE.N,GE.USD,USD,

(最後のカンマを取り除くには、最後のチェックを続ける必要があります。)

于 2012-05-08T21:42:03.617 に答える