2012-03-09 149 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一个程序化的方法来一次获得一定的金额。