我是XSL转换的新手,我想将XML A转换为XML B.任何在XSLT或xquery中实现此目的的建议。我尝试在msisdn上使用for-each-group 但仍然无法实现它。任何以
开头的示例代码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>
答案 0 :(得分:0)
这是一个解决方案,展示了如何实现分组和添加两个包装元素:
<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
,并且作为XSLT 2.0为分组提供的工具,只有我在正确的上下文中使用了正确的群体(select="response"
)( match="Output"
)。如果您很难理解,那么请尝试使用XSLT 2.0分组教程。由于您似乎想要处理组中的每个项目两次,我已经使用模式来执行此操作,因此要构建CombinedUsage
我已使用默认模式,以构建我使用过的SharedUsaged
一种不同的模式。其余的是为输入中的元素编写模板,以映射到输出中的元素,并确保不使用空模板复制特定模式的结果中不需要的元素。