[英]Complete xslt newbie. How do I merge these 2 xml sources in xslt version 1.0. applying grouping and sorting?
转化源
数据1.xml
<DEALERSHIP reg_number="01234567">
<MANUFACTURER name="VAUXHALL">
<CAR>
<CAR_VIN>12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>ASTRA</CAR_MODEL>
<CAR_REG_DATE>20060331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>HH54 RRY</CAR_REG>
<COLOUR>RED</COLOUR>
</CAR>
<CAR>
<CAR_VIN>12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>ASTRA</CAR_MODEL>
<CAR_REG_DATE>20040331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>HH54 RRY</CAR_REG>
<COLOUR>RED</COLOUR>
</CAR>
<CAR>
<CAR_VIN>12345678901234567</CAR_VIN>
<CAR_ENG>2.5</CAR_ENG>
<CAR_MODEL>CALIBRA</CAR_MODEL>
<CAR_REG_DATE>20030331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>HH54 RRY</CAR_REG>
<COLOUR>BLUE</COLOUR>
</CAR>
</MANUFACTURER>
<MANUFACTURER name="FORD">
<CAR>
<CAR_VIN>12345678901234567</CAR_VIN>
<CAR_ENG>2.5</CAR_ENG>
<CAR_MODEL>CMAX</CAR_MODEL>
<CAR_REG_DATE>20050331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>HH54 RRY</CAR_REG>
<COLOUR>RED</COLOUR>
</CAR>
</MANUFACTURER>
外部数据Data2.xml
<DEALERSHIP reg_number="01234567">
<MANUFACTURER name="VAUXHALL">
<CAR>
<CAR_VIN>XXX12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>ASTRA</CAR_MODEL>
<CAR_REG_DATE>20060331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>SS00 RRY</CAR_REG>
<COLOUR>BLUE</COLOUR>
</CAR>
<CAR>
<CAR_VIN>XXX12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>ASTRA</CAR_MODEL>
<CAR_REG_DATE>20060331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>SS00 RRY</CAR_REG>
<COLOUR>BLUE</COLOUR>
</CAR>
</MANUFACTURER>
<MANUFACTURER name="TOYOTA">
<CAR>
<CAR_VIN>XXX12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>Corolla</CAR_MODEL>
<CAR_REG_DATE>20030812</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>SS00 RRY</CAR_REG>
<COLOUR>RED</COLOUR>
</CAR>
</MANUFACTURER>
所需的输出
<DEALERSHIP reg_number="01234567">
<MANUFACTURER name="VAUXHALL">
<CAR>
<CAR_VIN>XXX12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>ASTRA</CAR_MODEL>
<CAR_REG_DATE>20060331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>SS00 RRY</CAR_REG>
<COLOUR>BLUE</COLOUR>
</CAR>
<CAR>
<CAR_VIN>XXX12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>ASTRA</CAR_MODEL>
<CAR_REG_DATE>20060331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>SS00 RRY</CAR_REG>
<COLOUR>RED</COLOUR>
</CAR>
<CAR>
<CAR_VIN>12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>ASTRA</CAR_MODEL>
<CAR_REG_DATE>20040331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>HH54 RRY</CAR_REG>
<COLOUR>RED</COLOUR>
</CAR>
<CAR>
<CAR_VIN>12345678901234567</CAR_VIN>
<CAR_ENG>2.5</CAR_ENG>
<CAR_MODEL>CALIBRA</CAR_MODEL>
<CAR_REG_DATE>20030331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>HH54 RRY</CAR_REG>
<COLOUR>BLUE</COLOUR>
</CAR>
</MANUFACTURER>
<MANUFACTURER name="FORD">
<CAR>
<CAR_VIN>12345678901234567</CAR_VIN>
<CAR_ENG>2.5</CAR_ENG>
<CAR_MODEL>CMAX</CAR_MODEL>
<CAR_REG_DATE>20050331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>HH54 RRY</CAR_REG>
<COLOUR>RED</COLOUR>
</CAR>
</MANUFACTURER>
<MANUFACTURER name="TOYOTA">
<CAR>
<CAR_VIN>XXX12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>Corolla</CAR_MODEL>
<CAR_REG_DATE>20030812</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>SS00 RRY</CAR_REG>
<COLOUR>RED</COLOUR>
</CAR>
</MANUFACTURER>
我第一次尝试xsl
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0" xmlns:externalSupplier="externalSupplier://uk.co.skyline.XslConnector"
xmlns:consol="consol://uk.co.skyline.Xslconsolidated"
exclude-result-prefixes="externalSupplier consol">
<xsl:output method="xml" />
<!-- *** Parameters *** -->
<!-- ****************** -->
<xsl:param name="dealerNo"></xsl:param> <!-- ** dealer Reg No being processed -->
<xsl:param name="supplier"></xsl:param>
<xsl:param name="cust"></xsl:param>
<!-- Load xml from external into variables -->
<!-- ************************************* -->
<!--
<xsl:variable name="externalStuff" select="externalSupplier:getData(
$dealerNo, $supplier, $cust)"></xsl:variable>
-->
<xsl:variable name="externalStuff"
select="document('Data2.xml')/*"></xsl:variable>
<xsl:template match="/">
<xsl:for-each select="DEALERSHIP">
<xsl:variable name="RegNum" select="@reg_number" />
<xsl:element name="{name()}">
<xsl:apply-templates select="." mode="copyAttributes" />
<xsl:for-each select="MANUFACTURER">
<xsl:variable name="manName" select="@name" />
<xsl:apply-templates select=".">
<xsl:with-param name="externalMan"
select="$externalStuff[@reg_number =
$RegNum]/MANUFACTURER[@name = $manName]" />
</xsl:apply-templates>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:template>
<!-- Process the MANUFACTURER elements -->
<!-- **************************** -->
<xsl:template match="MANUFACTURER">
<xsl:param name="externalMan" />
<!-- Get the reg number of the dealer -->
<xsl:variable name="regNum" select="../@reg_number" />
<!-- Get the manufacturer name -->
<xsl:variable name="eManName" select="@name" />
<xsl:element name="{name()}">
<xsl:apply-templates select="." mode="copyAttributes" />
<xsl:variable name="cars" select="CAR" />
<xsl:apply-templates
select="CAR | $externalMan/CAR[not (CAR_REG_DATE =
$cars/CAR_REG_DATE and CAR_MODEL = $cars/CAR_MODEL ) ]">
<xsl:sort select="CAR_REG_DATE" data-type="number"
order="descending" />
<xsl:sort select="CAR_MODEL" data-type="number"
order="descending" />
</xsl:apply-templates>
</xsl:element>
</xsl:template>
<!-- Process the CAR elements -->
<!-- **************************** -->
<xsl:template match="CAR">
<xsl:param name="externalMan" />
<xsl:choose>
<xsl:when test="CAR_VIN">
<xsl:copy-of select="." />
</xsl:when>
<xsl:otherwise>
<xsl:if
test="string-length(CAR_REG_DATE) = 8">
<CAR>
<xsl:copy-of select="*" />
<CAR_VIN>
<xsl:value-of
select="consol:getConSol(../../@reg_number,
CAR_REG_DATE, CAR_MODEL)" />
</CAR_VIN>
</CAR>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- Copy the element's attributes to the output -->
<!-- ******************************************* -->
<xsl:template match="DEALERSHIP | MANUFACTURER" mode="copyAttributes">
<xsl:for-each select="attribute::*">
<xsl:attribute name="{name()}"><xsl:value-of select="." />
</xsl:attribute>
</xsl:for-each>
</xsl:template>
这种转换发生在通过Java启动的服务器端。
从样式表中可以看到,我必须通过对某些Java处理的调用来包含Data2.xml。 我已将document()用于调试目的。
我设法从/到Java输入工作和xslt输出的主要结构的调用。 在任何数据中都不存在CAR_VIN的情况下,对java的调用发生在每个CAR元素的转换上。 给定的数据包括所有CAR_VIN,以避免对此Java进行调出。
它的xsl逻辑和代码与我刚接触的合并特别相关,需要一些帮助。
合并逻辑将数据源MANUFACTURERS和子元素组合在一起。 如果两个源都具有相同的CAR元素,并且其子元素CAR_REG_DATE和CAR_MODEL的内容相同,则仅包含Data1.xml或Data2.xml中的数据,以该唯一组合的最高计数为准。 如果组合在两个数据源中具有相同数量的数据,则使用转换源xml,在上述情况下为Data1.xml。 生成的元素需要按CAR_REG_DATE在每个MANUFATURER元素中降序排列。 因此,在以上数据示例中,您可以看到必要的输出包括所有MANUFACTURERS; 沃克斯豪尔,福特,丰田。 对于Vauxhall Astra 20060331,输出包含Data2.xml ASTRA 20060331中的数据,但不包括Data1.xml中的相同数据组合。所有其他Vauxhall Astra(非20060331)的情况都包含在Data1.xml的输出中。由CAR_REG_DATE降序排列的Ford Manaufacturer数据降序的每个MANUFACTURER都包含在Data1排序的CAR_REG_DATE desc的输出中。 Toyota Manaufacturer数据包含在Data2订购的CAR_REG_DATE desc的输出中。
我最初想到了使用联合运算符合并的想法,其中Data2.xml CAR_REG_DATE和CAR_MODEL内容值与Data1.xml CAR_REG_DATE不同,但是当没有匹配的数据CAR_REG_DATE和CAR_MODEL时,这将从Data2.xml中排除任何数据Data1.xml中的组合。 同样(当我考虑到这一点),当相同的组合CAR_REG_DATE和CAR_MODEL在DATA1.xml中时,它将始终从Data2.xsml中排除数据,而不管这两个数据源中的计数如何,这绝对不是我想要的。
应用stylesheet.xsl的结果
<?xml version="1.0" encoding="UTF-8"?>
12345678901234567 1.9 ASTRA 20060331 A HH54 RRY红色12345678901234567 1.9 ASTRA 20040331 A HH54 RRY红色12345678901234567 2.5 CALIBRA 20030331 A HH54 RRY蓝色12345678901234567 2.5 CMAX 20050331 A HH54 RRY红色
后来我想到了将源文档和外部文档都合并到局部变量中,然后将合并的MANUFACTURER传递到模板中并遍历每个CAR元素的想法。 我可以通过以XXX开头的CAR_VIN的内容来区分Data1.xml和Data2.xml CAR元素。所以我想我将遍历每个合并的CAR元素,并选择源文档和外部文档的计数,并基于以下内容包含外部或排除源结果。
这可能吗,我将如何去做?还是要牢记正确的方法,以确保我是xslt处理的新手?
对此问题的任何帮助将不胜感激。
嗨,谢谢你的回复
我已编辑数据集以避免rsi。
简而言之,我需要实现以下逻辑-
不论源Data1.xml或Data2.xml的CAR_REG_DATE和CAR_MODEL唯一组合的数量较多(在CAR内),输出中都包含源数据-排除具有相同组合的其他源数据。
这两个来源都必须包含所有CAR_REG_DATE-CAR_MODEL唯一组合。 一旦合并,在每个MANUFACTURER中降序的CAR_REG_DATE
因此,选择沃克斯豪尔制造商
Astra- 20060331的唯一组合-Data1.xml具有1和Data2.xml具有2。
我需要从为此组合设置的Data2.xml中输出Astras 20060331,而忽略Data1.xml Astras 20060331 1的出现,如上面的requiredoutput.xml所示
迪米我非常感谢您的评论。 我认为这是我的问题; 我试图查看问题并将其分解为较小的部分,但在这里失败了。 发现xsl:variable是不可变的,我仍然感到震惊。 (或者看起来)。
此样式表:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kCarByMan-Mod-Date"
match="CAR"
use="concat(../@name,'+',CAR_MODEL,'+',CAR_REG_DATE)"/>
<xsl:variable name="vSource2" select="document('Data2.xml')"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()|@*" mode="copy">
<xsl:call-template name="identity"/>
</xsl:template>
<xsl:template match="DEALERSHIP">
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="pSource2" select="$vSource2"/>
</xsl:apply-templates>
<xsl:apply-templates
select="$vSource2/*/MANUFACTURER[
not(@name = current()/*/@name)
]">
<xsl:with-param name="pSource2" select="/"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="MANUFACTURER">
<xsl:param name="pSource2"/>
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="pSource2" select="$pSource2"/>
</xsl:apply-templates>
<xsl:apply-templates
select="$pSource2/*/MANUFACTURER[
@name = current()/@name
]/node()">
<xsl:with-param name="pSource2" select="/"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="CAR"/>
<xsl:template
match="CAR[count(.|key('kCarByMan-Mod-Date',
concat(../@name,'+',CAR_MODEL,'+',CAR_REG_DATE)
)[1]
) = 1]">
<xsl:param name="pSource2"/>
<xsl:variable
name="vKey"
select="concat(../@name,'+',CAR_MODEL,'+',CAR_REG_DATE)"/>
<xsl:variable name="vGroup" select="key('kCarByMan-Mod-Date',$vKey)"/>
<xsl:for-each select="$pSource2">
<xsl:variable name="vGroup2"
select="key('kCarByMan-Mod-Date',$vKey)"/>
<xsl:apply-templates
select="$vGroup[not(count($vGroup2) > count($vGroup))]"
mode="copy"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
输出:
<DEALERSHIP reg_number="01234567">
<MANUFACTURER name="VAUXHALL">
<CAR>
<CAR_VIN>12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>ASTRA</CAR_MODEL>
<CAR_REG_DATE>20040331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>HH54 RRY</CAR_REG>
<COLOUR>RED</COLOUR>
</CAR>
<CAR>
<CAR_VIN>12345678901234567</CAR_VIN>
<CAR_ENG>2.5</CAR_ENG>
<CAR_MODEL>CALIBRA</CAR_MODEL>
<CAR_REG_DATE>20030331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>HH54 RRY</CAR_REG>
<COLOUR>BLUE</COLOUR>
</CAR>
<CAR>
<CAR_VIN>XXX12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>ASTRA</CAR_MODEL>
<CAR_REG_DATE>20060331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>SS00 RRY</CAR_REG>
<COLOUR>BLUE</COLOUR>
</CAR>
<CAR>
<CAR_VIN>XXX12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>ASTRA</CAR_MODEL>
<CAR_REG_DATE>20060331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>SS00 RRY</CAR_REG>
<COLOUR>BLUE</COLOUR>
</CAR>
</MANUFACTURER>
<MANUFACTURER name="FORD">
<CAR>
<CAR_VIN>12345678901234567</CAR_VIN>
<CAR_ENG>2.5</CAR_ENG>
<CAR_MODEL>CMAX</CAR_MODEL>
<CAR_REG_DATE>20050331</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>HH54 RRY</CAR_REG>
<COLOUR>RED</COLOUR>
</CAR>
</MANUFACTURER>
<MANUFACTURER name="TOYOTA">
<CAR>
<CAR_VIN>XXX12345678901234567</CAR_VIN>
<CAR_ENG>1.9</CAR_ENG>
<CAR_MODEL>Corolla</CAR_MODEL>
<CAR_REG_DATE>20030812</CAR_REG_DATE>
<TRANSMISSION>A</TRANSMISSION>
<CAR_REG>SS00 RRY</CAR_REG>
<COLOUR>RED</COLOUR>
</CAR>
</MANUFACTURER>
</DEALERSHIP>
注意 :按制造商,型号和日期分组。 遍历Data1.xml
。 DEALERSHIP
规则(从匹配节点Data1.xml
唯一的):自我复制,具有应用模板儿童Data2.xml
作为第二个来源,从应用模板厂家Data2.xml
不存在Data1.xml
。 MANUFACTURER
规则(匹配来自Data1.xml
和Data2.xml
节点):复制自身,将模板应用到具有pSource2
参数作为第二个源的子级,将模板应用到第二个源中属于同一制造商的CAR
(对于来自Data2.xml
不存在Data1.xml
)。 空CAR
默认规则。 “第一种” CAR
规则:如果第二个来源的同一组中没有更多项目,则复制当前组(这意味着对于相同数量的项目,两个都将被复制。 如果不需要,请澄清行为。 )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.