XSLT 2.0 按另一个样式表中的变量排序
Posted
技术标签:
【中文标题】XSLT 2.0 按另一个样式表中的变量排序【英文标题】:XSLT 2.0 Sort by variable from another style sheet 【发布时间】:2020-01-16 19:46:16 【问题描述】:我需要创建按从另一个 XSLT 中提取的数值排序的 XML,我将其用作交叉引用。 以下源 XML (source.xml) 在 Partner/Header/@whse 处有四个字母字符。
<?xml version="1.0" encoding="UTF-8"?>
<Partner partnerId="TradingPartner1">
<Header whse="NCCH" >
<Contract claimNumber="00000000" />
</Header>
<Header whse="TXAU" >
<Contract claimNumber="00000000" />
</Header>
<Header whse="LANO" >
<Contract claimNumber="00000000" />
</Header>
<Header whse="MIGR">
<Contract claimNumber="00000000" />
</Header>
<Header whse="TXHO">
<Contract claimNumber="00000000" />
</Header>
</Partner>
我需要交叉引用字母字符以获取 DUNS+4。 我使用这个 XSLT (Duns_config.xslt) 来获取 DUNS。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="SHIPTODUNS">
<xsl:param name="Whse" />
<xsl:choose>
<xsl:when test="$Whse = 'LANO'"><xsl:value-of select="'0044893600101'" /></xsl:when>
<xsl:when test="$Whse = 'TXHO'"><xsl:value-of select="'0044893600103'" /></xsl:when>
<xsl:when test="$Whse = 'TXAU'"><xsl:value-of select="'0044893600105'" /></xsl:when>
<xsl:when test="$Whse = 'NCCH'"><xsl:value-of select="'0044893600214'" /></xsl:when>
<xsl:when test="$Whse = 'MIGR'"><xsl:value-of select="'8949713340601'" /></xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
在主 XSLT (Transaction.xslt) 中,我包含了 Duns_config.xslt 并调用 SHIPTODUNS 将数据放入变量 $headerDuns。 然后我得到 DUNS+4 的最后三位,并将它们放入变量 $varWhse 并尝试按此变量排序:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:include href="Duns_config.xslt"/>
<xsl:template match="Partner">
<Partner partnerId="./@partnerId">
<xsl:apply-templates select="./Header" />
</Partner>
</xsl:template>
<xsl:template match="Header">
<xsl:variable name="headerDuns">
<xsl:call-template name = "SHIPTODUNS">
<xsl:with-param name="Whse" select="./@whse" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="varWhse">
<xsl:value-of select="substring($headerDuns, 11, 3)" />
</xsl:variable>
<xsl:for-each select="current()">
<xsl:sort select="$varWhse" />
<transaction varwhse="$varWhse">
<duns number="$headerDuns" />
</transaction>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出未按 $varWhse 排序:
<?xml version="1.0" encoding="UTF-8"?>
<Partner partnerId="TradingPartner1">
<transaction varwhse="214">
<duns number="0044893600214"/>
</transaction>
<transaction varwhse="105">
<duns number="0044893600105"/>
</transaction>
<transaction varwhse="101">
<duns number="0044893600101"/>
</transaction>
<transaction varwhse="601">
<duns number="8949713340601"/>
</transaction>
<transaction varwhse="103">
<duns number="0044893600103"/>
</transaction>
</Partner>
我希望数据像这样出来:
<?xml version="1.0" encoding="UTF-8"?>
<Partner partnerId="TradingPartner1">
<transaction varwhse="101">
<duns number="0044893600101"/>
</transaction>
<transaction varwhse="103">
<duns number="0044893600103"/>
</transaction>
<transaction varwhse="105">
<duns number="0044893600105"/>
</transaction>
<transaction varwhse="214">
<duns number="0044893600214"/>
</transaction>
<transaction varwhse="601">
<duns number="8949713340601"/>
</transaction>
</Partner>
有人看到我做错了什么或有其他方法吗? 这是我在这个网站上的第一篇文章。这是很多信息,我希望它是有道理的。
【问题讨论】:
这是未来的有用参考 【参考方案1】:您的代码的一个问题是您的Header
模板中的xsl:sort
不是第一条指令; xsl:sort
必须是第一条指令。另一个问题是排序出现在Header
模板中,但它必须应用于更高级别。要纠正这些错误,必须对模板进行一些重组。
对于以下解决方案,我选择将所有逻辑放入一个模板中 - 分两步:
-
用包含
item
元素的子数据结构填充名为mapping
的变量。
使用排序 xsl:for-each
遍历该变量并输出transaction
元素。
结果如下:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:include href="Duns_config.xslt"/>
<xsl:template match="Partner">
<Partner partnerId="./@partnerId">
<xsl:variable name="mapping">
<xsl:for-each select="Header">
<xsl:variable name="headerDuns">
<xsl:call-template name = "SHIPTODUNS">
<xsl:with-param name="Whse" select="@whse" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="varWhse">
<xsl:value-of select="substring($headerDuns, 11, 3)" />
</xsl:variable>
<item>
<whse><xsl:value-of select="$varWhse" /></whse>
<duns><xsl:value-of select="$headerDuns" /></duns>
</item>
</xsl:for-each>
</xsl:variable>
<xsl:for-each select="$mapping/item">
<xsl:sort select="whse" /> <!-- See how xsl:sort is the first instruction -->
<transaction varwhse="whse">
<duns number="duns"/>
</transaction>
</xsl:for-each>
</Partner>
</xsl:template>
</xsl:stylesheet>
它的输出是:
<?xml version="1.0" encoding="UTF-8"?>
<Partner partnerId="TradingPartner1">
<transaction varwhse="101">
<duns number="0044893600101"/>
</transaction>
<transaction varwhse="103">
<duns number="0044893600103"/>
</transaction>
<transaction varwhse="105">
<duns number="0044893600105"/>
</transaction>
<transaction varwhse="214">
<duns number="0044893600214"/>
</transaction>
<transaction varwhse="601">
<duns number="8949713340601"/>
</transaction>
</Partner>
如你所愿。
【讨论】:
感谢您的帮助。我能够将它应用到我的 XSLT 并获得所需的结果!!我从来没有想过一个变量里面有一个变量......更不用说一个里面的两个了:)。这实际上开辟了一种完全不同的思维方式来解决我将来遇到的问题!!!!【参考方案2】:得到choose
的结果后应用排序。发生的情况是您仍在生成 xml 输出,但您在 Header
项目级别对其进行排序。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:include href="Duns_config.xslt"/>
<xsl:template match="Partner">
<xsl:variable name="partial">
<PartnerTemp partnerId="./@partnerId">
<xsl:apply-templates select="./Header" />
</PartnerTemp>
</xsl:variable>
<xsl:apply-templates select="$partial"></xsl:apply-templates>
</xsl:template>
<xsl:template match="PartnerTemp">
<Partner partnerId="./@partnerId">
<xsl:perform-sort select="transaction">
<xsl:sort select="@varwhse"/>
</xsl:perform-sort>
</Partner>
</xsl:template>
<xsl:template match="Header">
<xsl:variable name="headerDuns">
<xsl:call-template name = "SHIPTODUNS">
<xsl:with-param name="Whse" select="./@whse" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="varWhse">
<xsl:value-of select="substring($headerDuns, 11, 3)" />
</xsl:variable>
<xsl:for-each select="current()">
<transaction varwhse="$varWhse">
<duns number="$headerDuns" />
</transaction>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
【讨论】:
这个解决方案也有效!感谢您提供另一种获得相同结果的方法。以上是关于XSLT 2.0 按另一个样式表中的变量排序的主要内容,如果未能解决你的问题,请参考以下文章