将具有相似名称的标签转换为特定格式

时间:2014-05-15 15:25:45

标签: xml xslt

我是xml xslt的新手。 我需要使用xslt将xml转换为特定格式。 需要查找类似的标签名称并将其转换为特定格式 我的意见:

  <?xml version="1.0" encoding="UTF-8"?>
      <tpso xmlns="packetware:teleprovision" xmlns:xsi="http://www.w3.org/2001/XMLSchema-  instance" xsi:schemaLocation="tpso.xsd">
     <rollback>true</rollback>
        <soid>000027041866009@ALL</soid>
     <purpose>CHANGE</purpose>
       <description>tpso for Element ALL Action CHANGE</description>
       <failureAction>4</failureAction>
      <executeOnDate>2013-10-07T11:22:21.000+00:00</executeOnDate>
           <priority>8</priority>
           <subscriberID>260060059948580</subscriberID>
          <subscriberDN>48727554404</subscriberDN>
         <parameters>
           <parameter>
            <name>MSISDN</name>
           <value>48727554404</value>
       </parameter>
        </parameters>
           <serviceActions>

       <serviceAction>
                  <name>usage_state</name>
                <reference/>
             <parameters>
                     <parameter>
                        <name>action</name>
                          <value>add</value>
                   </parameter>
                    <parameter>
                      <name>old</name>
                 <value/>
                   </parameter>
                     <parameter>
                       <name>new</name>
                        <value>0ghfgfg</value>
                    </parameter>
                 </parameters>
             </serviceAction>

     <serviceAction>
        <name>usage_state</name>
        <reference/>
        <parameters>
            <parameter>
                <name>action</name>
                <value>add</value>
            </parameter>
            <parameter>
                <name>old</name>
                <value/>
            </parameter>
            <parameter>
                <name>new</name>
                <value>1ghfgfg</value>
            </parameter>
        </parameters>
    </serviceAction>

     <serviceAction>
        <name>usage_state</name>
        <reference/>
        <parameters>
            <parameter>
                <name>action</name>
                <value>add</value>
            </parameter>
            <parameter>
                <name>old</name>
                <value/>
            </parameter>
            <parameter>
                <name>new</name>
                <value>2ghfgfg</value>
            </parameter>
        </parameters>
    </serviceAction>

     <serviceAction>
        <name>usage_state</name>
        <reference/>
        <parameters>
            <parameter>
                <name>action</name>
                <value>add</value>
            </parameter>
            <parameter>
                <name>old</name>
                <value/>
            </parameter>
            <parameter>
                <name>new</name>
                <value>3ghfgfg</value>
            </parameter>
        </parameters>
    </serviceAction>
     <serviceAction>
        <name>usage_state</name>
        <reference/>
        <parameters>
            <parameter>
                <name>action</name>
                <value>add</value>
            </parameter>
            <parameter>
                <name>old</name>
                <value/>
            </parameter>
            <parameter>
                <name>new</name>
                <value>4ghfgfg</value>
            </parameter>
        </parameters>
    </serviceAction>
    </serviceActions>

        </tpso>

输出需要如下所示

           "usage_state": { "0" : {"operation": "add","value" : "0ghfgfg"},
                "1" : {"operation": "add","value" : "1ghfgfg"},
                "2" : {"operation": "add","value" : "2ghfgfg"},
                "3" : {"operation": "add","value" : "3ghfgfg"},
                "4" : {"operation": "add","value" : "4ghfgfg"}}

我不知道如何继续。任何帮助将不胜感激。

XSLT用于提取唯一标记的值              下面是我写的xsl。现在需要将你的部分和我的部分联系起来。                                                                

    <xsl:for-each select="/pw:tpso/pw:serviceActions/pw:serviceAction">
    <xsl:choose>
     <xsl:when test="pw:parameters/pw:parameter/pw:name[string()='action']/../pw:value = 'add'">
      "<xsl:value-of select="pw:name"/>" : {"operation": "add","value" : "<xsl:value-of select="pw:parameters/pw:parameter/pw:name[string()='new']/../pw:value"/>"}
     </xsl:when>
     <xsl:when test="pw:parameters/pw:parameter/pw:name[string()='action']/../pw:value = 'del'">
      "<xsl:value-of select="pw:name"/>" : {"operation": "del","value" : "         <xsl:value-of select="pw:parameters/pw:parameter/pw:name[string()='old']/../pw:value"/>"}
     </xsl:when>
     <xsl:when test="pw:parameters/pw:parameter/pw:name[string()='action']/../pw:value = 'def'">
      "<xsl:value-of select="pw:name"/>" : {"operation": "def","value" : "<xsl:value-of select="pw:parameters/pw:parameter/pw:name[string()='new']/../pw:value"/>"}
     </xsl:when>
     <xsl:when test="pw:parameters/pw:parameter/pw:name[string()='action']/../pw:value = 'chg'">
      "<xsl:value-of select="pw:name"/>" : {"operation": "chg","newvalue" : "<xsl:value-of select="pw:parameters/pw:parameter/pw:name[string()='new']/../pw:value"/>", "oldvalue" : "<xsl:value-of select="pw:parameters/pw:parameter/pw:name[string()='old']/../pw:value"/>" }
     </xsl:when>

 “”:{“operation”:“def”,“value”:“”}                  

    </xsl:choose>
</xsl:for-each>

输出需要如下所示         “billing_model”:{ “操作”: “删除”, “值”: “2”}          “block_data_transfer”:{ “操作”: “DEF”, “值”: “NONE”}          “BSG”:{ “操作”: “删除”, “值”: “”}

输入                                         真正              000027041866009 @ ALL               更改             元素所有动作改变的tpso             4              2013-10-07T11:22:21.000 + 00:00                   8            260060059948580            48727554404                                       MSISDN             48727554404                                                            usage_state                                                                行动                     加                                                       旧                                                                            新                     0ghfgfg                                                                        usage_state                                                                行动                     加                                                       旧                                                                            新                     1ghfgfg                                                                        usage_state                                                                行动                     加                                                       旧                                                                            新                     2ghfgfg                                                                             usage_state                                                                行动                     加                                                       旧                                                                            新                     3ghfgfg                                                                                usage_state                                                                行动                     加                                                       旧                                                                            新                     4ghfgfg                                                                                 block_data_transfer                                                                行动                     高清                                                       旧                     没有                                                       新                     没有                                                                       BSG                                                                行动                     德尔                                                       旧                                                                            新                                                                                               billing_model                                                                行动                     德尔                                                       旧                                                                            新                     2                                                                               

1 个答案:

答案 0 :(得分:1)

这是分组问题的一个例子。如果您使用的是XSLT 1.0,那么您需要阅读Muenchian Grouping,这通常是处理此类问题的最有效方法。

我假设您按名称 serviceAction 元素进行分组,因此您首先要定义一个键来查找 serviceAction 元素名称

 <xsl:key name="service" match="t:serviceAction" use="t:name" />

(注意,这里的 t:前缀是因为在原始XML中,所有元素都在命名空间中=&#34; packetware:teleprovision&#34;,所以你需要在你的XSLT中也声明了这一点。在这种情况下我使用前缀 t 作为声明。)

然后,要获得构成组的基础的不同名称元素,表达式如下:

<xsl:apply-templates select="t:serviceActions/t:serviceAction
                             [generate-id() = generate-id(key('service', t:name)[1])]" />

查看所有 serviceAction 元素,找到当前名称值的键中出现的第一个元素。

然后,要获取每个组中的元素,您可以迭代键,如下所示:

<xsl:for-each select="key('service', t:name)">

试试这个XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:t="packetware:teleprovision">
    <xsl:output method="text"/>
    <xsl:key name="service" match="t:serviceAction" use="t:name" />

    <xsl:variable name="quote">"</xsl:variable>

    <xsl:template match="/*">
        <xsl:apply-templates select="t:serviceActions/t:serviceAction[generate-id() = generate-id(key('service', t:name)[1])]" />
    </xsl:template>

    <xsl:template match="t:serviceAction">
        "<xsl:value-of select="t:name" />": <xsl:text>{</xsl:text>
        <xsl:for-each select="key('service', t:name)">
            <xsl:if test="position() > 1">,</xsl:if>
            "<xsl:number />" : {
                "operation": "<xsl:value-of select="t:parameters/t:parameter[t:name='action']/t:value" />",
                "value" : "<xsl:value-of select="t:parameters/t:parameter[t:name='new']/t:value" />"
            <xsl:text>}</xsl:text>
        </xsl:for-each>
        }
    </xsl:template>
</xsl:stylesheet>

这将输出以下内容

    "usage_state": {
        "1" : {
            "operation": "add",
            "value" : "0ghfgfg"
        },
        "2" : {
            "operation": "add",
            "value" : "1ghfgfg"
        },
        "3" : {
            "operation": "add",
            "value" : "2ghfgfg"
        },
        "4" : {
            "operation": "add",
            "value" : "3ghfgfg"
        },
        "5" : {
            "operation": "add",
            "value" : "4ghfgfg"
        }
    }

注意,在XSLT 2.0中,您可以使用xsl:for-each-group而不是Muenchian分组方法来简化操作。