我的本地会计系统有一个输出,它由一个信封标签和一个重复的字段序列组成,但没有分组。我以前没有XSL的经验,但一直试图找到一个解决方案,并找到了适用于XSLT 2.0的解决方案。不幸的是,似乎Access 2007只接受XSLT 1.0转换。
你能帮我找一个有效的XSLT 1.0解决方案吗?
这是原始平面XML中的两个记录:
<ENVELOPE>
<DBCFIXED> <DBCDATE>1-Apr-2011</DBCDATE>
<DBCPARTY></DBCPARTY>
</DBCFIXED>
<DBCVCHTYPE>Stock Journal</DBCVCHTYPE>
<DBCVCHNO>1</DBCVCHNO>
<DBCVCHREF></DBCVCHREF>
<DBCSTNO></DBCSTNO>
<DBCSERVICETAXNO></DBCSERVICETAXNO>
<DBCPANNO></DBCPANNO>
<DBCCSTNO></DBCCSTNO>
<DBCNARR>Opening balance transfar</DBCNARR>
<DBCQTY>0.000 Kg</DBCQTY>
<DBCRATE></DBCRATE>
<DBCAMOUNT></DBCAMOUNT>
<DBCADDLCOST></DBCADDLCOST>
<DBCGROSSAMT></DBCGROSSAMT>
<DBCLEDAMT></DBCLEDAMT>
<DBCFIXED> <DBCDATE></DBCDATE>
<DBCPARTY>ME KN YARN BL 1</DBCPARTY>
</DBCFIXED>
<DBCVCHTYPE></DBCVCHTYPE>
<DBCVCHNO></DBCVCHNO>
<DBCVCHREF></DBCVCHREF>
<DBCSTNO></DBCSTNO>
<DBCSERVICETAXNO></DBCSERVICETAXNO>
<DBCPANNO></DBCPANNO>
<DBCCSTNO></DBCCSTNO>
<DBCNARR></DBCNARR>
<DBCQTY>0.150 Kg</DBCQTY>
<DBCRATE>566.00/Kg</DBCRATE>
<DBCAMOUNT>-84.90</DBCAMOUNT>
<DBCADDLCOST></DBCADDLCOST>
<DBCGROSSAMT></DBCGROSSAMT>
<DBCLEDAMT></DBCLEDAMT>
</ENVELOPE>
对于导入Access,我需要将数据分组到以DBCFIXED开头的记录中,直到下一个DBCFIXED。类似的东西:
<InventoryDaybook>
<record>
<DBCFIXED>
<DBCDATE>1-Apr-2011</DBCDATE>
<DBCPARTY/>
</DBCFIXED>
<DBCVCHTYPE>Stock Journal</DBCVCHTYPE>
<...></...>
</record>
<record>
<...></...>
</record>
/<InventoryDaybook>
有效的XSLT 2.0代码是
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/*">
<InventoryDaybook>
<xsl:for-each-group select="*" group-starting-with="DBCFIXED">
<record>
<xsl:copy-of select="current-group()"/>
</record>
</xsl:for-each-group>
</InventoryDaybook>
</xsl:template>
</xsl:stylesheet>
使用XSL可以做些什么是令人惊讶的,但我的知识似乎太少了......提前感谢您的帮助和理解。
答案 0 :(得分:1)
祝贺蒂姆第一个正确的解决方案。虽然蒂姆是完全正确的,但我只是想引起OP的注意,有两种一般形式的解决方案,XSLT 1.0组 - 起始 - 一个头节点被排除在密钥之外(如Tim的情况),以及包含头节点的另一个(如下所示)。我不确定哪个优越。也许迪米特可以告诉我们。
因此,为了感兴趣,这里是替代形式,其中包括密钥中的头节点。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="records" match="ENVELOPE/*" use="generate-id(
(preceding-sibling::DBCFIXED|self::DBCFIXED)[last()])" />
<xsl:template match="/ENVELOPE">
<InventoryDaybook>
<xsl:apply-templates select="DBCFIXED" mode="group-head" />
</InventoryDaybook>
</xsl:template>
<xsl:template match="DBCFIXED" mode="group-head">
<record>
<xsl:apply-templates select="key('records', generate-id())" />
</record>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
这可以通过 xsl:key 在XSLT1.0中实现,它匹配非DBCFIXED元素,并使用前面的第一个DBCFIXED元素作为键
<xsl:key
name="records"
match="ENVELOPE/*[not(self::DBCFIXED)]"
use="generate-id(preceding-sibling::DBCFIXED[1])" />
然后,当您匹配单个 DBCFIXED 元素时,您可以轻松查找构成记录的关联元素
<xsl:apply-templates select="key('records', generate-id())" />
这是完整的XLST
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="records" match="ENVELOPE/*[not(self::DBCFIXED)]" use="generate-id(preceding-sibling::DBCFIXED[1])" />
<xsl:template match="/ENVELOPE">
<InventoryDaybook>
<xsl:apply-templates select="DBCFIXED" />
</InventoryDaybook>
</xsl:template>
<xsl:template match="DBCFIXED">
<record>
<xsl:copy-of select="." />
<xsl:apply-templates select="key('records', generate-id())" />
</record>
</xsl:template>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
当应用于输入XML时,输出以下内容
<InventoryDaybook>
<record>
<DBCFIXED>
<DBCDATE>1-Apr-2011</DBCDATE>
<DBCPARTY/>
</DBCFIXED>
<DBCVCHTYPE>Stock Journal</DBCVCHTYPE>
<DBCVCHNO>1</DBCVCHNO>
<DBCVCHREF/>
<DBCSTNO/>
<DBCSERVICETAXNO/>
<DBCPANNO/>
<DBCCSTNO/>
<DBCNARR>Opening balance transfar</DBCNARR>
<DBCQTY>0.000 Kg</DBCQTY>
<DBCRATE/>
<DBCAMOUNT/>
<DBCADDLCOST/>
<DBCGROSSAMT/>
<DBCLEDAMT/>
</record>
<record>
<DBCFIXED>
<DBCDATE/>
<DBCPARTY>ME KN YARN BL 1</DBCPARTY>
</DBCFIXED>
<DBCVCHTYPE/>
<DBCVCHNO/>
<DBCVCHREF/>
<DBCSTNO/>
<DBCSERVICETAXNO/>
<DBCPANNO/>
<DBCCSTNO/>
<DBCNARR/>
<DBCQTY>0.150 Kg</DBCQTY>
<DBCRATE>566.00/Kg</DBCRATE>
<DBCAMOUNT>-84.90</DBCAMOUNT>
<DBCADDLCOST/>
<DBCGROSSAMT/>
<DBCLEDAMT/>
</record>
</InventoryDaybook>