2012-03-09 150 views
2

我有以下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批次,並寫入單獨PSV的每個50學生,所以前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的微軟processer那麼傷心不支持v2.0,因此必須是v1.0 XSLT

最好的做法是使用標準的xslt1.0版本, onal組件不是最容易做的事情。

+0

請提供確切的結果。另外,不是每個人都可以猜測PSV的含義 - 我目前的猜測是「管道分離值」。請編輯問題並提供這些必要的信息。 – 2012-03-09 14:23:26

+0

當然,XSLT是「程序化的」:) – 2012-03-09 14:24:09

+0

我之後可以批量處理數據(例如,400名學生,只有50個到.txt文件,因此製作8個文件)而不是實際的輸出結構你給了,正如我在下面的例子XML中所述。 – Mike 2012-03-12 13:16:14

回答

1

純XSLT 1.0不可能生成多個結果文檔

要做到這一點,您需要調用一個擴展函數(您必須編寫)來將元素保存在單獨的文件中。

您需要閱讀您的MSDN文檔how to write an extension function

變換

<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. 全部Pupil開始新批處理的元素將被處理(以匿名模式)。

  3. 如果需要,該批次包裝在batch元素中(如果不是,則可能會刪除該代碼)。然後包含當前批次的所有Pupil元素都將在"inbatch"模式下處理,併爲其中的每個元素生成必要的CSV輸入。

  4. iutput被捕獲到名爲$vrtfBatch的變量中。使用參數$vrtfBatch和此批次的序列號調用擴展功能(必須編寫)my:writeResult。擴展函數必須創建一個新文件(使用seq。no,文件名)並在其中寫入內容。

+0

你能解釋一下在這裏發生在高層次背後的邏輯嗎? – Mike 2012-03-13 14:03:42

0

你可以使用xslt來做到這一點。 Here is good example how to do it

+0

你碰巧知道微軟命名空間的重定向,因爲它是爲特定處理器編寫的 – Mike 2012-03-09 13:15:00

+0

實際上,沒有什麼直接類似於msxml中的「重定向」,但你可以寫一個Javascript方法,它接受結果樹片段作爲參數,並使用Microsoft的DOM實現中可用的方法對其進行序列化。 – 2012-03-09 14:22:28

+0

不幸的是,我不知道關於JavaScript的一件事情,所以一個出來的規則 – Mike 2012-03-12 11:24:54

0

我回答類似的問題here一個程序化的方法來一次獲得一定的金額。