我是第一次接触XSL转换,我想用.Any或xquery将XML转换成XML。我尝试在msisdn上使用for-each-group,但仍然无法实现it.Any示例代码
XML A:
<Output>
<response>
<msisdn>27832007509</msisdn>
<bearer>DATA</bearer>
<comb_charged_units>4223777792</comb_charged_units>
<comb_cnt>288</comb_cnt>
<shared_voice_duration>0</shared_voice_duration>
<shared_data_volume>8728127</shared_data_volume>
<shared_voice_cnt>0</shared_voice_cnt>
<shared_data_cnt>89</shared_data_cnt>
</response>
<response>
<msisdn>27832007509</msisdn>
<bearer>VOICE</bearer>
<comb_charged_units>477792</comb_charged_units>
<comb_cnt>281</comb_cnt>
<shared_voice_duration>17268127877</shared_voice_duration>
<shared_data_volume>0</shared_data_volume>
<shared_voice_cnt>87887</shared_voice_cnt>
<shared_data_cnt>0</shared_data_cnt>
</response>
<response>
<msisdn>27832229588</msisdn>
<bearer>DATA</bearer>
<comb_charged_units>11898</comb_charged_units>
<comb_cnt>33</comb_cnt>
<shared_voice_duration>0</shared_voice_duration>
<shared_data_volume>3445</shared_data_volume>
<shared_voice_cnt>0</shared_voice_cnt>
<shared_data_cnt>78</shared_data_cnt>
</response>
<response>
<msisdn>27832229588</msisdn>
<bearer>VOICE</bearer>
<comb_charged_units>45</comb_charged_units>
<comb_cnt>12</comb_cnt>
<shared_voice_duration>789</shared_voice_duration>
<shared_data_volume>0</shared_data_volume>
<shared_voice_cnt>23</shared_voice_cnt>
<shared_data_cnt>0</shared_data_cnt>
</response>
XML B:
<UsageHistoryResponse>
<usage>
<MSISDN>27832007509</MSISDN>
<CombinedUsage>
<usage_info>
<bearer>DATA</bearer>
<bearer_units>288</bearer_units>
<bearer_units_uom>Sessions</bearer_units_uom>
<bearer_usage>4223777792</bearer_usage>
<bearer_usage_uom>bytes</bearer_usage_uom>
</usage_info>
<usage_info>
<bearer>VOICE</bearer>
<bearer_units>281</bearer_units>
<bearer_units_uom>Calls</bearer_units_uom>
<bearer_usage>477792</bearer_usage>
<bearer_usage_uom>Seconds</bearer_usage_uom>
</usage_info>
</CombinedUsage>
<SharedUsage>
<usage_info>
<bearer>DATA</bearer>
<bearer_units>89</bearer_units>
<bearer_units_uom>Sessions</bearer_units_uom>
<bearer_usage>8728127</bearer_usage>
<bearer_usage_uom>bytes</bearer_usage_uom>
</usage_info>
<usage_info>
<bearer>VOICE</bearer>
<bearer_units>87887</bearer_units>
<bearer_units_uom>Calls</bearer_units_uom>
<bearer_usage>17268127877</bearer_usage>
<bearer_usage_uom>Seconds</bearer_usage_uom>
</usage_info>
</SharedUsage>
</usage>
<usage>
<MSISDN>27832229588</MSISDN>
<CombinedUsage>
<usage_info>
<bearer>DATA</bearer>
<bearer_units>33</bearer_units>
<bearer_units_uom>Sessions</bearer_units_uom>
<bearer_usage>11898</bearer_usage>
<bearer_usage_uom>bytes</bearer_usage_uom>
</usage_info>
<usage_info>
<bearer>VOICE</bearer>
<bearer_units>12</bearer_units>
<bearer_units_uom>Calls</bearer_units_uom>
<bearer_usage>45</bearer_usage>
<bearer_usage_uom>Seconds</bearer_usage_uom>
</usage_info>
</CombinedUsage>
<SharedUsage>
<usage_info>
<bearer>DATA</bearer>
<bearer_units>78</bearer_units>
<bearer_units_uom>Sessions</bearer_units_uom>
<bearer_usage>3445</bearer_usage>
<bearer_usage_uom>bytes</bearer_usage_uom>
</usage_info>
<usage_info>
<bearer>VOICE</bearer>
<bearer_units>23</bearer_units>
<bearer_units_uom>Calls</bearer_units_uom>
<bearer_usage>789</bearer_usage>
<bearer_usage_uom>Seconds</bearer_usage_uom>
</usage_info>
</SharedUsage>
</usage>
我的想法是首先对msisdn进行分组,然后遍历其中的字段。下面是我的尝试
<xsl:template match="/">
<tns:UsageHistoryResponse>
<xsl:for-each select="/Output/response">
<tns:usage>
<xsl:for-each-group select="." group-by="ns0:msisdn">
<tns:MSISDN>
<xsl:value-of select="current-grouping-key()"/></tns:MSISDN>
</xsl:for-each-group>
</tns:usage>
</xsl:for-each>
</tns:UsageHistoryResponse>
</xsl:template>发布于 2017-07-18 23:49:47
下面是一个解决方案,展示了如何实现两个包装器元素的分组和添加:
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()" mode="#all">
<xsl:copy>
<xsl:apply-templates select="@* | node()" mode="#current"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Output">
<UsageHistoryResponse>
<xsl:for-each-group select="response" group-by="msisdn">
<usage>
<MSISDN>
<xsl:value-of select="current-grouping-key()"/>
</MSISDN>
<CombinedUsage>
<xsl:apply-templates select="current-group()"/>
</CombinedUsage>
<SharedUsage>
<xsl:apply-templates select="current-group()" mode="shared"/>
</SharedUsage>
</usage>
</xsl:for-each-group>
</UsageHistoryResponse>
</xsl:template>
<xsl:template match="response" mode="#default shared">
<usage_info>
<xsl:apply-templates mode="#current"/>
</usage_info>
</xsl:template>
<xsl:template match="msisdn" mode="#all"/>
<xsl:template match="response/*[starts-with(local-name(), 'shared')]"/>
<xsl:template match="response/*[starts-with(local-name(), 'comb')]" mode="shared"/>
<xsl:template match="comb_cnt">
<bearer_units>
<xsl:apply-templates/>
</bearer_units>
</xsl:template>
</xsl:transform>http://xsltransform.net/bEzjRKb/1展示了它的优势
<?xml version="1.0" encoding="UTF-8"?>
<UsageHistoryResponse>
<usage>
<MSISDN>27832007509</MSISDN>
<CombinedUsage>
<usage_info>
<bearer>DATA</bearer>
<comb_charged_units>4223777792</comb_charged_units>
<bearer_units>288</bearer_units>
</usage_info>
<usage_info>
<bearer>VOICE</bearer>
<comb_charged_units>477792</comb_charged_units>
<bearer_units>281</bearer_units>
</usage_info>
</CombinedUsage>
<SharedUsage>
<usage_info>
<bearer>DATA</bearer>
<shared_voice_duration>0</shared_voice_duration>
<shared_data_volume>8728127</shared_data_volume>
<shared_voice_cnt>0</shared_voice_cnt>
<shared_data_cnt>89</shared_data_cnt>
</usage_info>
<usage_info>
<bearer>VOICE</bearer>
<shared_voice_duration>17268127877</shared_voice_duration>
<shared_data_volume>0</shared_data_volume>
<shared_voice_cnt>87887</shared_voice_cnt>
<shared_data_cnt>0</shared_data_cnt>
</usage_info>
</SharedUsage>
</usage>
<usage>
<MSISDN>27832229588</MSISDN>
<CombinedUsage>
<usage_info>
<bearer>DATA</bearer>
<comb_charged_units>11898</comb_charged_units>
<bearer_units>33</bearer_units>
</usage_info>
<usage_info>
<bearer>VOICE</bearer>
<comb_charged_units>45</comb_charged_units>
<bearer_units>12</bearer_units>
</usage_info>
</CombinedUsage>
<SharedUsage>
<usage_info>
<bearer>DATA</bearer>
<shared_voice_duration>0</shared_voice_duration>
<shared_data_volume>3445</shared_data_volume>
<shared_voice_cnt>0</shared_voice_cnt>
<shared_data_cnt>78</shared_data_cnt>
</usage_info>
<usage_info>
<bearer>VOICE</bearer>
<shared_voice_duration>789</shared_voice_duration>
<shared_data_volume>0</shared_data_volume>
<shared_voice_cnt>23</shared_voice_cnt>
<shared_data_cnt>0</shared_data_cnt>
</usage_info>
</SharedUsage>
</usage>
</UsageHistoryResponse>因此,有一些工作需要重命名元素,这可以通过添加模板来实现,然后您似乎还想添加一些数据,我不确定这些数据像在哪里
<bearer_usage_uom>Seconds</bearer_usage_uom>应该是从。
至于解释:我已经按照您的需要使用了for-each-group,并且作为XSLT2.0提供的分组工具,只是我在正确的上下文(match="Output")中使用了正确的群体(select="response")。如果您很难理解这一点,请尝试阅读关于XSLT 2.0分组的教程。由于您似乎希望将一个组中的每个项目处理两次,因此我使用了模式来实现这一点,因此,为了构建CombinedUsage,我使用了默认模式,为了构建SharedUsaged,我使用了不同的模式。剩下的工作是为输入中的元素编写模板,将其映射到输出中的元素,并确保不希望在特定模式的结果中出现的元素不会通过使用空模板进行复制。
https://stackoverflow.com/questions/45170275
复制相似问题