我有一个报告生成器工具,可以为不同类型的报告生成XML文档。每个XML文档都有一组字段(报告:以下XML文档中的列),用于描述其中的实际数据(报告:以下XML文档中的行)。由于字段列表是动态的并且对于每种报告都在不断变化,因此如何编写使用“字段”将数据转换为csv文件的通用XSL模板。
我的示例XML文档:
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<reporting:root xmlns:reporting="http://www.something.net/reporting">
<reporting:default0 reporting:type="Portfolio">
<reporting:header>
<reporting:configuration>
<reporting:columns>
<reporting:column reporting:group="instrument" reporting:name="Ident" reporting:tag="ident" reporting:type="int"/>
<reporting:column reporting:group="prices" reporting:name="Last (Time)" reporting:tag="lastTime" reporting:type="string"/>
<reporting:column reporting:group="noGroup" reporting:name="RIC" reporting:tag="ric" reporting:type="string"/>
<reporting:column reporting:group="instrument" reporting:name="Reference" reporting:tag="reference" reporting:type="string"/>
<reporting:column reporting:group="result" reporting:name="Currency" reporting:tag="currency" reporting:type="string"/>
</reporting:columns>
</reporting:configuration>
</reporting:header>
<reporting:window reporting:Id="36674" reporting:level="0" reporting:name="MY_PORTFOLIO" reporting:parentId="11991">
<reporting:line reporting:Id="67520135" reporting:level="1" reporting:name="INTERNATIONAL BUSINESS MACHINES CORP" reporting:parentId="36674" reporting:positionType="0">
<reporting:ident>643633</reporting:ident>
<reporting:reference>IBM.USD</reporting:reference>
<reporting:currency>USD</reporting:currency>
</reporting:line>
<reporting:line reporting:Id="67520179" reporting:level="1" reporting:name="GENERAL ELECTRIC CO" reporting:parentId="36674" reporting:positionType="0">
<reporting:ident>643635</reporting:ident>
<reporting:ric>GE.N</reporting:ric>
<reporting:reference>GE.USD</reporting:reference>
<reporting:currency>USD</reporting:currency>
</reporting:line>
</reporting:window>
</reporting:default0>
</reporting:root>
我需要看到输出格式如下:
ident,lastTime,ric,reference,currency
643633,,,IBM.USD,USD
643635,,GE.N,GE.USD,USD
我做了一些工作但是已经过了一半。无法找到如何处理“动态”字段列表并将其用作描述实际数据的标记。
有人可以帮忙吗?
感谢。
答案 0 :(得分:1)
在XSLT中有各种解决方法,但我认为最优雅和可维护的是编写一个处理给定源文档的样式表,并输出一个XSLT样式表来进行实际报告。我已经看到这种方法在许多项目中都非常成功。
答案 1 :(得分:0)
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="/*:root/*:default0/*:header/*:configuration/*:columns/*:column">
<xsl:value-of select="@reporting:tag"/>
<xsl:text>,</xsl:text>
</xsl:for-each>
<xsl:for-each select="/*:root/*:default0/*:window/*:line">
<xsl:variable name="theline" select="."/>
<xsl:text>
</xsl:text>
<xsl:for-each select="/*:root/*:default0/*:header/*:configuration/*:columns/*:column" >
<xsl:variable name="oname" select="@reporting:tag" />
<xsl:value-of select="$theline/*[local-name()=$oname]" /><xsl:text>,</xsl:text>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
将产生:
IDENT,lastTime,RIC,参考,货币,
643633 ,,, IBM.USD,美元,
643635,GE.N,GE.USD,美元,
(你需要坚持检查最后一个以删除最后一个逗号。)
答案 2 :(得分:0)
尝试
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:r="http://www.something.net/reporting">
<xsl:output method="text" version="1.0"/>
<xsl:template match="/">
<xsl:for-each select="/r:root/r:default0/r:header/r:configuration/r:columns/r:column">
<xsl:value-of select="@r:tag"/>
<xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
<xsl:for-each select="/r:root/r:default0/r:window/r:line">
<xsl:variable name="POSITION" select="position()"/>
<xsl:for-each select="//r:root/r:default0/r:header/r:configuration/r:columns/r:column">
<xsl:variable name="TAGNAME" select="@r:tag"/><xsl:value-of select="//r:line[$POSITION]/*[local-name()=$TAGNAME]"/><xsl:if test="position() != last()">,</xsl:if>
</xsl:for-each>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
请注意,我只是缩短了名称空间前缀,以便于阅读(和键入)。
答案 3 :(得分:0)
这个简短而简单的转型:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:r="http://www.something.net/reporting">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vColNames" select="/*/*/r:header/*/*/*/@r:tag"/>
<xsl:template match="/">
<xsl:for-each select="$vColNames">
<xsl:value-of select="concat(., ',')"/>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="r:line">
<xsl:variable name="vThis" select="."/>
<xsl:text>
</xsl:text>
<xsl:for-each select="$vColNames">
<xsl:if test="position() > 1">,</xsl:if>
<xsl:apply-templates select="$vThis/*[local-name() = current()]"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
在提供的XML文档上运行时:
<reporting:root xmlns:reporting="http://www.something.net/reporting">
<reporting:default0 reporting:type="Portfolio">
<reporting:header>
<reporting:configuration>
<reporting:columns>
<reporting:column reporting:group="instrument" reporting:name="Ident" reporting:tag="ident" reporting:type="int"/>
<reporting:column reporting:group="prices" reporting:name="Last (Time)" reporting:tag="lastTime" reporting:type="string"/>
<reporting:column reporting:group="noGroup" reporting:name="RIC" reporting:tag="ric" reporting:type="string"/>
<reporting:column reporting:group="instrument" reporting:name="Reference" reporting:tag="reference" reporting:type="string"/>
<reporting:column reporting:group="result" reporting:name="Currency" reporting:tag="currency" reporting:type="string"/>
</reporting:columns>
</reporting:configuration>
</reporting:header>
<reporting:window reporting:Id="36674" reporting:level="0" reporting:name="MY_PORTFOLIO" reporting:parentId="11991">
<reporting:line reporting:Id="67520135" reporting:level="1" reporting:name="INTERNATIONAL BUSINESS MACHINES CORP" reporting:parentId="36674" reporting:positionType="0">
<reporting:ident>643633</reporting:ident>
<reporting:reference>IBM.USD</reporting:reference>
<reporting:currency>USD</reporting:currency>
</reporting:line>
<reporting:line reporting:Id="67520179" reporting:level="1" reporting:name="GENERAL ELECTRIC CO" reporting:parentId="36674" reporting:positionType="0">
<reporting:ident>643635</reporting:ident>
<reporting:ric>GE.N</reporting:ric>
<reporting:reference>GE.USD</reporting:reference>
<reporting:currency>USD</reporting:currency>
</reporting:line>
</reporting:window>
</reporting:default0>
</reporting:root>
生成想要的正确结果:
ident,lastTime,ric,reference,currency,
643633,,,IBM.USD,USD
643635,,GE.N,GE.USD,USD