Xml XSLT生成另一个XSLT脚本
在这个线程中,我引用了我的最后一个线程: 引用线程中的XSLT脚本工作正常,但对于大型XML文档,性能并不好。现在我想编写一个XSLT脚本,输出另一个XSLT脚本,该脚本将输出最终的CSV文件 问题: 如何编写第一个XSLT脚本?输出应如下所示:Xml XSLT生成另一个XSLT脚本,xml,xslt,Xml,Xslt,在这个线程中,我引用了我的最后一个线程: 引用线程中的XSLT脚本工作正常,但对于大型XML文档,性能并不好。现在我想编写一个XSLT脚本,输出另一个XSLT脚本,该脚本将输出最终的CSV文件 问题: 如何编写第一个XSLT脚本?输出应如下所示: <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/*">
<xsl:text>Name;</xsl:text>
<xsl:text>Brother;</xsl:text>
<xsl:text>Sister</xsl:text>
<-- this part is dynamic -->
<xsl:apply-templates select="Person" />
</xsl:template>
<xsl:template match="Person">
<xsl:value-of select="Name" />
<xsl:value-of select="Brother" />
<xsl:value-of select="Sister" />
<-- this part is dynamic too -->
<xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>
名称
兄弟
姐妹
输入XML文件与引用线程中的相同:
<Person>
<Name>John</Name>
<FamilyMembers>
<FamilyMember>
<Name>Lisa</Name>
<Type>Sister</Type>
</FamilyMember>
<FamilyMember>
<Name>Tom</Name>
<Type>Brother</Type>
</FamilyMember>
</FamilyMembers>
</Person>
<Person>
<Name>Daniel</Name>
<FamilyMembers>
<FamilyMember>
<Name>Peter</Name>
<Type>Father</Type>
</FamilyMember>
</FamilyMembers>
</Person>
约翰
丽莎
姐妹
汤姆
兄弟
丹尼尔
彼得
父亲
对于每个不同类型的元素,在生成的XSLT脚本中应该有一行如下所示:
<xsl:text>Type;</xsl:text>
类型;
要编写一个XSLT输出另一个XSLT,您需要使用
生成输出元素,例如
<xsl:element name="xsl:text">
如果要使用文字结果元素,请使用
。政府有一个例子:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
xmlns:axsl="http://www.w3.org/1999/XSL/TransformAlias">
<xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>
<xsl:template match="/">
<axsl:stylesheet>
<xsl:apply-templates/>
</axsl:stylesheet>
</xsl:template>
样式表中的任何
元素都将成为输出中的
。而不是两个外部阶段的解决方案(意味着编写一个执行的样式表的样式表),我认为Tim解决方案的一个版本会更好地满足您的需求,它在规模上表现得更好。请使用“大型XML文档”作为输入来衡量此解决方案的性能
此XSLT 1.0样式表…
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:key name="kTypes" match="Type" use="." />
<xsl:variable name="distinct-types"
select="/*/Person/FamilyMembers/FamilyMember/Type[
generate-id()=generate-id(key('kTypes',.)[1])]" />
<xsl:template match="/">
<xsl:value-of select="'Name;'" />
<xsl:for-each select="$distinct-types">
<xsl:value-of select="." />
<xsl:if test="position() < last()">
<xsl:value-of select="';'" />
</xsl:if>
</xsl:for-each>
<xsl:value-of select="'
'" />
<xsl:apply-templates select="*/Person" />
</xsl:template>
<xsl:template match="Person">
<xsl:value-of select="concat(Name,';')" />
<xsl:variable name="family" select="FamilyMembers/FamilyMember" />
<xsl:for-each select="$distinct-types">
<xsl:variable name="type" select="string(.)" />
<xsl:value-of select="$family/self::*[Type=$type]/Name" />
<xsl:if test="position() < last()">
<xsl:value-of select="';'" />
</xsl:if>
</xsl:for-each>
<xsl:value-of select="'
'" />
</xsl:template>
</xsl:stylesheet>
<t>
<Person>
<Name>John</Name>
<FamilyMembers>
<FamilyMember>
<Name>Lisa</Name>
<Type>Sister</Type>
</FamilyMember>
<FamilyMember>
<Name>Tom</Name>
<Type>Brother</Type>
</FamilyMember>
</FamilyMembers>
</Person>
<Person>
<Name>Daniel</Name>
<FamilyMembers>
<FamilyMember>
<Name>Peter</Name>
<Type>Father</Type>
</FamilyMember>
</FamilyMembers>
</Person>
</t>
Name;Sister;Brother;Father
John;Lisa;Tom;
Daniel;;;Peter
请参见为另一个XSLT转换生成样式表的XSLT转换的实际示例:
实际上,您不需要两个外部相的解决方案。您所需要做的就是提高Tim解决方案的规模效率。你应该问的真正问题是如何在规模上进行优化。我会做测试并给出反馈。可能需要一些时间。你的解决方案最适合我的问题。使用axsl是我的实际方式。稍后我将测试Sean的解决方案。