[英]match and merge in XSLT with optional nodes
我有一个示例XML消息,其中包含多个父节点。 要求是,如果两个父节点相同,则合并子节点。 当所有节点都存在时,此方法工作正常,但在不存在可选节点时,则无效
样本消息:1带有可选节点
<document>
<body>
<party>
<gtin>1000909090</gtin>
<pos>
<attrGroupMany name="temperatureInformation">
<row>
<gtin>1000909090</gtin>
<attr name="temperatureCode">STORAGE</attr>
<attrQualMany name="temperature">
<value qual="FAH">10</value>
<value qual="CC">20</value>
</attrQualMany>
<attrGroupMany name="temperatureStats"> <!-- optional group -->
<row>
<attr name="StatsCode">CODE1</attr>
</row>
<row>
<attr name="StatsCode">CODE2</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="temperatureCode">STORAGE</attr>
<attrQualMany name="temperature">
<value qual="FAH">10</value>
<value qual="CC">20</value>
</attrQualMany>
<attrGroupMany name="temperatureStats"> <!-- optional group -->
<row>
<attr name="StatsCode">CODE3</attr>
</row>
<row>
<attr name="StatsCode">CODE4</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="temperatureCode">HANDLING</attr>
<attrQualMany name="temperature">
<value qual="FAH">10</value>
</attrQualMany>
<attrGroupMany name="temperatureStats"> <!-- optional group -->
<row>
<attr name="StatsCode">CODE5</attr>
</row>
<row>
<attr name="StatsCode">CODE6</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="temperatureCode">HANDLING</attr>
<attrGroupMany name="temperatureStats"> <!-- optional group -->
<row>
<attr name="StatsCode">CODE7</attr>
</row>
<row>
<attr name="StatsCode">CODE8</attr>
</row>
</attrGroupMany>
</row>
</attrGroupMany>
</pos>
</party>
</body>
</document>
下面的示例XSLT可以很好地从'attrGroupMany name =“ temperatureInformation”'中删除重复项
使用XSLT
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:key name="group" match="party/pos/attrGroupMany[@name = 'temperatureInformation']/row"
use="concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature'])"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="attrGroupMany[@name = 'temperatureInformation']">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="row[generate-id() = generate-id(key('group', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))[1])]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="attrGroupMany[@name = 'temperatureStats']">
<xsl:copy>
<xsl:apply-templates select="@* | key('group', concat(generate-id(ancestor::pos), '|',../attr[@name = 'temperatureCode'], '|', ../attrQualMany[@name = 'temperature']))/attrGroupMany[@name = 'temperatureStats']/row"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
与以上XSLT不兼容的示例消息2是
<document>
<body>
<party>
<gtin>1000909090</gtin>
<pos>
<attrGroupMany name="temperatureInformation">
<row>
<gtin>1000909090</gtin>
<attr name="temperatureCode">STORAGE</attr>
<attrQualMany name="temperature">
<value qual="FAH">10</value>
<value qual="CC">20</value>
</attrQualMany>
</row>
<row>
<attr name="temperatureCode">STORAGE</attr>
<attrQualMany name="temperature">
<value qual="FAH">10</value>
<value qual="CC">20</value>
</attrQualMany>
<attrGroupMany name="temperatureStats"> <!-- optional group -->
<row>
<attr name="StatsCode">CODE3</attr>
</row>
<row>
<attr name="StatsCode">CODE4</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="temperatureCode">HANDLING</attr>
<attrQualMany name="temperature">
<value qual="FAH">10</value>
</attrQualMany>
<attrGroupMany name="temperatureStats"> <!-- optional group -->
<row>
<attr name="StatsCode">CODE5</attr>
</row>
<row>
<attr name="StatsCode">CODE6</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="temperatureCode">HANDLING</attr>
<attrGroupMany name="temperatureStats"> <!-- optional group -->
<row>
<attr name="StatsCode">CODE7</attr>
</row>
<row>
<attr name="StatsCode">CODE8</attr>
</row>
</attrGroupMany>
</row>
</attrGroupMany>
</pos>
</party>
</body>
</document>
有人可以让我知道如何处理比赛n合并中的可选节点
示例消息2的预期输出为
<?xml version="1.0" encoding="UTF-8"?>
<document>
<body>
<party>
<gtin>1000909090</gtin>
<pos>
<attrGroupMany name="temperatureInformation">
<row>
<gtin>1000909090</gtin>
<attr name="temperatureCode">STORAGE</attr>
<attrQualMany name="temperature">
<value qual="FAH">10</value>
<value qual="CC">20</value>
</attrQualMany>
<attrGroupMany name="temperatureStats">
<row>
<attr name="StatsCode">CODE3</attr>
</row>
<row>
<attr name="StatsCode">CODE4</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="temperatureCode">HANDLING</attr>
<attrQualMany name="temperature">
<value qual="FAH">10</value>
</attrQualMany>
<attrGroupMany name="temperatureStats">
<row>
<attr name="StatsCode">CODE5</attr>
</row>
<row>
<attr name="StatsCode">CODE6</attr>
</row>
</attrGroupMany>
</row>
<row>
<attr name="temperatureCode">HANDLING</attr>
<attrGroupMany name="temperatureStats">
<row>
<attr name="StatsCode">CODE7</attr>
</row>
<row>
<attr name="StatsCode">CODE8</attr>
</row>
</attrGroupMany>
</row>
</attrGroupMany>
</pos>
</party>
</body>
</document>
有人可以让我知道如何在比赛n合并中处理可选节点。 谢谢
您尚未解释要执行的操作背后的逻辑,但是通过查看此问题以及以前的问题的XSLT,您可以将attrGroupMany[@name = 'temperatureInformation']/row
元素分组,但是将祖先pos
以及“ temperatureCode”和“ temperature”。
然后,对于每个这样的不同row
,您似乎都想添加所有<attrGroupMany name="temperatureStats">
元素。 如果您说模板是可选的,那么与该元素匹配的模板将无法工作。 而是要有一个与父row
匹配的模板,并使用该模板从键中的所有元素中选择所有子元素。
<xsl:template match="attrGroupMany[@name = 'temperatureInformation']/row">
<xsl:copy>
<xsl:apply-templates select="@*|node()[not(self::attrGroupMany[@name = 'temperatureStats'])]"/>
<attrGroupMany name="temperatureStats">
<xsl:apply-templates select="key('group', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))/attrGroupMany[@name = 'temperatureStats']/row"/>
</attrGroupMany>
</xsl:copy>
</xsl:template>
我假设所有StatsCode
在这里都是不同的。 如果可能有重复项,并且您想删除此类重复项,则需要在问题中这样说。
试试这个XSLT:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="group" match="party/pos/attrGroupMany[@name = 'temperatureInformation']/row"
use="concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature'])"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="attrGroupMany[@name = 'temperatureInformation']">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="row[generate-id() = generate-id(key('group', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))[1])]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="attrGroupMany[@name = 'temperatureInformation']/row">
<xsl:copy>
<xsl:apply-templates select="@*|node()[not(self::attrGroupMany[@name = 'temperatureStats'])]"/>
<attrGroupMany name="temperatureStats">
<xsl:apply-templates select="key('group', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))/attrGroupMany[@name = 'temperatureStats']/row"/>
</attrGroupMany>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes" />
<xsl:key name="grouptemperatureInformation" match="party/pos/attrGroupMany[@name = 'temperatureInformation']/row"
use="concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature'])"/>
<xsl:key name="grouptemperatureStats"
match="party/pos/attrGroupMany[@name = 'temperatureInformation']/row/attrGroupMany[@name = 'temperatureStats']/row"
use="concat(generate-id(ancestor::pos), '|', ../../../attr[@name = 'temperatureCode'], '|', ../../../attrQualMany[@name = 'temperature'], '|', attr[@name = 'StatsCode'])"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="attrGroupMany[@name = 'temperatureInformation']">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:apply-templates select="row[generate-id() = generate-id(key('grouptemperatureInformation', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))[1])]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="attrGroupMany[@name = 'temperatureInformation']/row">
<xsl:variable name="group" select="key('grouptemperatureInformation', concat(generate-id(ancestor::pos), '|', attr[@name = 'temperatureCode'], '|', attrQualMany[@name = 'temperature']))/attrGroupMany[@name='temperatureStats']/row" />
<xsl:copy>
<xsl:apply-templates select="@*|node()[not(self::attrGroupMany[@name = 'temperatureStats'])]"/>
<attrGroupMany name="temperatureStats">
<xsl:apply-templates select="@* | $group[generate-id() = generate-id(key('grouptemperatureStats', concat(generate-id(ancestor::pos), '|', ../../../attr[@name = 'temperatureCode'], '|', ../../../attrQualMany[@name = 'temperature'], '|', attr[@name = 'StatsCode']))[1])]"/>
</attrGroupMany>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.