2012-03-09 24 views
2

I以下のXML構造を持っている:XSLTバッチ処理

<School> 
    <SchoolInfo> 
    <SchoolName>The Big School</SchoolName> 
    <Opened>2008</Opened> 
    <SchoolID>SCH1122</SchoolID> 
    <Geograpics> 
     <Location>London</Location> 
     <PostCode>ZZ11 1ZZ</PostCode> 
    </Geographics> 
    </SchoolInfo> 
    <Pupil> 
    <Name>Tom</Name> 
    <LastName>Jones</LastName> 
    <Class>12B</Class> 
    <Age>16</Age> 
    </Pupil> 
    <Pupil> 
    <Name>Steve</Name> 
    <LastName>Jobs</LastName> 
    <Class>09A</Class> 
    <Age>17</Age> 
    </Pupil> 
    <Pupil> 
    <Name>Joe</Name> 
    <LastName>Blogs</LastName> 
    <Class>13A</Class> 
    <Age>15</Age> 
    </Pupil> 
</School> 

私のXML構造が...言う400人の生徒含まれていたと私は50のバッチでそれらを処理し、各50のためにPSVのを区切るために書きたい場合生徒、最初の50、次に50-100、そして100-150などと新しいファイルに各バッチを書く..これはXSLTを使用して行うことができますか、それはプログラム的でなければならないでしょうか?

私はPSVなどに処理するコードを持っています。私はかなり率直にも手がかりを持っていないので、バッチ処理の仕方について行っています。

- PSV:パイプ区切りが

SCH1122|London|Tom|12B|16 
SCH1122|London|Steve|09A|17 
SCH1122|London|Joe|13A|15 

値以下のようにXMLを変換するために使用されるコードは次のとおりです。

private string PerformTransformation(string FilePath) 
{ 
    string fullXsltFile; 

    if (chkDateIncrement.Checked == false) 
     fullXsltFile = Resources.XSLTTest; // Resources.XSLT; 
    else 
     fullXsltFile = Resources.XSLTTest; 

    XmlDocument xsltTransformDocument = new XmlDocument(); 
    xsltTransformDocument.LoadXml(fullXsltFile); 

    FileInfo xmlFileInfo = new FileInfo(FilePath); 
    string outputFile = CreateXmlOutputFileName(xmlFileInfo); 

    // load the Xslt with any settings 
    XslCompiledTransform transformation = new XslCompiledTransform(); 
    XsltSettings settings = new XsltSettings(true, false); 
    settings.EnableScript = true; 
    transformation.Load(xsltTransformDocument, settings, new XmlUrlResolver()); 

    using (XmlReader reader = XmlReader.Create(FilePath)) 
    { 
     using (FileStream stream = new FileStream(outputFile, FileMode.Create)) 
     { 
      transformation.Transform(reader, null, stream); 
      stream.Close(); 
     } 
     reader.Close(); 
    } 
    return outputFile; 
} 

私もそう悲しげにVS2010でのMicrosoftののプロセサを使用していませんv2.0をサポートするため、v1.0にする必要があります。XSLT

標準のxslt1.0ビルドでこれを行う方法は、addit onalコンポーネントは最も簡単なことではありません。

+0

正確な結果を提供してください。また、PSVが意味することを誰もが推測できるわけではありません。私の現在の推測は「パイプで区切られた値」です。質問を編集し、必要な情報を入力してください。 –

+0

そして、もちろん、XSLTは "プログラム"です:) –

+0

私はその後、実際の出力構造ではなくデータをバッチ処理する能力があります(例えば、400人の瞳孔と50の.txtファイルしか持たないので8つのファイルにする)。あなたが与えたのは、下の段落のXMLの例で述べたとおりです。 – Mike

答えて

1

純粋なXSLT 1.0では複数の結果ドキュメントを生成することはできません。

これを行うには、要素を別のファイルに保存するための拡張機能(書き込む必要があります)を呼び出す必要があります。

how to write an extension functionについては、MSDNのドキュメントを参照する必要があります。

変換

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:my="my:my" exclude-result-prefixes="my"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pBatchLength" select="2"/> 

<xsl:variable name="vId" select="/*/SchoolInfo/SchoolID"/> 
<xsl:variable name="vLoc" select="/*/SchoolInfo/Geographics/Location"/> 

<xsl:template match="/*"> 
    <xsl:apply-templates select="Pupil[position() mod $pBatchLength = 1]"/> 
</xsl:template> 

<xsl:template match="Pupil"> 
    <xsl:variable name="vrtfBatch"> 
    <batch> 
     <xsl:apply-templates mode="inbatch" select= 
     ". | following-sibling::Pupil[not(position() > $pBatchLength -1)]"/> 
    </batch> 
    </xsl:variable> 

    <xsl:value-of select= 
     "my:writeResult($vrtfBatch, ceiling(position() div $pBatchLength))"/> 
</xsl:template> 

<xsl:template match="Pupil" mode="inbatch"> 
    <xsl:value-of select= 
    "concat('&#xA;', $vId, '|', $vLoc, '|', Name, '|', Class, '|', Age)"/> 
</xsl:template> 
<xsl:template match="text()"/> 
</xsl:stylesheet> 

説明

  1. "バッチ" の所望の長さのため(外部/グローバルパラメータ$pBatchLength、そのデフォルト値で指定されています私たちの小さなデモの例は2と定義されています)。

  2. すべてPupilPupil新しいバッチを開始する要素はすべて(匿名モードで)処理されます。

  3. バッチはbatch要素でラップされています(存在しない場合は、このコードは削除される可能性があります)。次に、現在のバッチを含むすべてのPupil要素が"inbatch"モードで処理され、それぞれに必要なCSV入力が生成されます。

  4. iutputは、$vrtfBatchという名前の変数に取り込まれます。拡張機能(あなたが書かなければならない)my:writeResultは、パラメータ:$vrtfBatchとこのバッチのシーケンス番号で呼び出されます。拡張機能は、新しいファイルを作成し(ファイル名にseq。noを使用)、内容を書き込む必要があります。

+0

ここで何が起こったのかという背後にある論理を説明できますか? – Mike

0

これはxsltを使用して行うことができます。 Here is good example how to do it

+0

特定のプロセッサ用に書かれたリダイレクトのMicrosoft名前空間を知っていますか – Mike

+0

実際には、msxmlの "redirect"に直接類似するものはありませんが、結果ツリーフラグメントをパラメータとして受け取り、MicrosoftのDOM実装で利用可能なメソッド を使用してそれをシリアル化するJavascriptメソッドです。 –

+0

悲しいことに、私はJavaScriptのことを知らないので、そのうちのルールを – Mike

0

私は同様の質問hereに一度に一定量を得るためのプログラム的なアプローチについて答えます。