C# 批处理
我有以下XML结构:C# 批处理,c#,xml,xslt,batch-processing,C#,Xml,Xslt,Batch Processing,我有以下XML结构: <School> <SchoolInfo> <SchoolName>The Big School</SchoolName> <Opened>2008</Opened> <SchoolID>SCH1122</SchoolID> <Geograpics> <Location>London</Location
<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的代码如下所示:
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中使用microsofts processer,因此很遗憾,它不支持v2.0,因此必须是v1.0 XSLT
最好使用标准xslt1.0构建来实现这一点,因为加入其他组件不是最容易的事情。您可以使用 纯XSLT 1.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>
说明:
<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
)元素(在匿名模式下)
batch
元素中(否则,可能会删除此代码)。然后在“inbatch”
模式下处理构成当前批次的所有元素,并为每个元素生成必要的CSV输入
$vrtfBatch
的变量中。使用以下参数调用扩展函数(您必须编写)my:writeResult
:$vrtfBatch
和该批的序列号。扩展函数必须创建一个新文件(使用seq.no作为文件名)并在其中写入内容您是否知道重定向的Microsoft命名空间,因为它是为特定的进程编写的。实际上,msxml中没有与“重定向”直接类似的内容,但您可以编写一个Javascript方法,该方法接受结果树片段作为参数,遗憾的是,我对javascript一无所知,所以输出的规则能够提供准确的结果。而且,不是每个人都能猜到PSV的意思——我目前的猜测是“管道分隔值”。请编辑这个问题并提供必要的信息。当然,XSLT是“编程的”:)我需要批处理数据的能力(例如400个学生,一个.txt文件只有50个,所以生成8个文件),而不是您给出的实际输出结构,正如我在下面的一段中所述,示例XML中没有提到创建不同的文件。请编辑问题并添加此缺少的要求。此外,在纯XSLT1.0中不可能创建多个输出文件。您需要一个XSLT 2.0处理器,或者一个带有扩展元素
EXSLT:document
的EXSLT实现的XSLT处理器,或者您需要编写自己的扩展函数。请在问题中具体说明您正在寻找哪些可能的解决方案。按要求编辑,您更喜欢广泛的功能。您能否从较高的层次解释这里发生的事情背后的逻辑?