我熟悉 XSLT 的基础知识,但我遇到了一个我似乎无法弄清楚的奇怪情况。对于这么长时间,我深表歉意,但我非常感谢您能提供的任何帮助。
我正在对由我无法控制的软件产品生成的 XML 进行转换。该产品导出的数据如下所示:
<header>
<data>
</data>
</header>
<transaction>
<B1_PG1 ts='1139977698718.75'><data></data></B1_PG1>
<B1_PG2 ts='1139977698718.76'><data></data></B1_PG2>
<B2_PG1 ts='1139977698718.77'><data></data></B2_PG1>
<B2_PG2 ts='1139977698718.78'><data></data></B2_PG2>
<B2_PG1 ts='1139977698718.79'><data></data></B2_PG1>
<B2_PG2 ts='1139977698718.80'><data></data></B2_PG2>
<B3_PG1 ts='1139977698718.81'><data></data></B3_PG1>
</transaction>
软件产品按照接收数据的顺序导出数据页面。我需要获取这些页面并按自定义顺序对它们进行排序,以便处理到另一个系统中。因此,我创建了一个看起来像这样的查找文档来定义我的自定义排序顺序:
(PageSequences.xml)
<pages>
<page id="B2_PG1" sequence="1000" />
<page id="B2_PG2" sequence="1010" />
<page id="B3_PG1" sequence="2000" />
<page id="B1_PG1" sequence="3000" />
<page id="B1_PG2" sequence="3010" />
</pages>
然后,我根据元素名称查找该序列,将其与时间戳连接,并使用以下 XSLT 将属性注入元素:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name='page-seqs' select='document("PageSequences.xml")/pages/page'/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()">
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="transaction">
<transaction>
<xsl:for-each select="child::node()">
<xsl:variable name='localname' select='local-name()'/>
<xsl:copy>
<xsl:attribute name="sequence">
<xsl:value-of select='$page-seqs[@id=$localname]/@sequence'/>-<xsl:value-of select='@ts'/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()">
<xsl:sort select="@sequence" />
</xsl:apply-templates>
</xsl:copy>
</xsl:for-each>
</transaction>
</xsl:template>
</xsl:stylesheet>
我遇到的问题是标签似乎不起作用。我期望以下内容:
<transaction>
<B2_PG1 ts='1139977698718.77' sequence='1000-1139977698718.77'><data></data></B2_PG1>
<B2_PG1 ts='1139977698718.79' sequence='1000-1139977698718.79'><data></data></B2_PG1>
<B2_PG2 ts='1139977698718.78' sequence='1010-1139977698718.78'><data></data></B2_PG2>
<B2_PG2 ts='1139977698718.80' sequence='1010-1139977698718.80'><data></data></B2_PG2>
<B3_PG1 ts='1139977698718.81' sequence='2000-1139977698718.81'><data></data></B3_PG1>
<B1_PG1 ts='1139977698718.75' sequence='3000-1139977698718.75'><data></data></B1_PG1>
<B1_PG2 ts='1139977698718.76' sequence='3010-1139977698718.76'><data></data></B1_PG2>
</transaction>
但我得到:
<transaction>
<B1_PG1 ts='1139977698718.75' sequence='3000-1139977698718.75'><data></data></B1_PG1>
<B1_PG2 ts='1139977698718.76' sequence='3010-1139977698718.76'><data></data></B1_PG2>
<B2_PG1 ts='1139977698718.77' sequence='1000-1139977698718.77'><data></data></B2_PG1>
<B2_PG2 ts='1139977698718.78' sequence='1010-1139977698718.78'><data></data></B2_PG2>
<B2_PG1 ts='1139977698718.79' sequence='1000-1139977698718.79'><data></data></B2_PG1>
<B2_PG2 ts='1139977698718.80' sequence='1010-1139977698718.80'><data></data></B2_PG2>
<B3_PG1 ts='1139977698718.81' sequence='2000-1139977698718.81'><data></data></B3_PG1>
</transaction>
此外,如果您认为我以错误的方式处理此问题,请告诉我。我试图避免使用 java/c#/perl/etc... 以尽可能保持转换的可移植性。出于性能原因,我还想避免执行两次转换。谢谢!