XSLT Batch Processing
本文关键字:Processing Batch XSLT | 更新日期: 2023-09-27 18:27:25
我有以下XML结构:
<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的微软处理器,所以很遗憾不支持v2.0,因此必须是v1.0 XSLT
最好使用标准xslt1.0构建来实现这一点,因为引入额外的组件不是最容易的事情。
使用纯XSLT1.0不可能生成多个结果文档。
要做到这一点,您需要调用一个扩展函数(您必须编写该函数)来将元素保存在一个单独的文件中。
您需要阅读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('
', $vId, '|', $vLoc, '|', Name, '|', Class, '|', Age)"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
解释:
"批"的所需长度在外部/全局参数
$pBatchLength
中指定,其默认值(对于我们的小演示示例,定义为2
)。将处理所有启动新批处理的
Pupil
元素(以匿名模式)。如有必要,将批处理封装在
batch
元素中(否则,可能会删除此代码)。然后,在"inbatch"
模式下处理包括当前批次的所有Pupil
元素,并为它们中的每一个生成必要的CSV输入。iutput被捕获在一个名为
$vrtfBatch
的变量中。扩展函数(您必须编写)my:writeResult
被调用,参数为:$vrtfBatch
和该批次的序列号。扩展函数必须创建一个新文件(使用seq.no作为文件名),并在其中写入内容。
您可以使用可扩展样式表(xslt)来完成此操作。