首页 > 解决方案 > oracle Insbridge flat xml 结构与属性 xslt 转换

问题描述

我需要将平面 xml 转换为分层 xml 结构。目标元素需要映射到与源 xml 不同的级别。我结束了多次循环 XML 以创建目标 xml。将 // 与属性名称一起使用似乎也不是一个好主意,因为 xml 可能很大并且可能导致性能问题。

我想了解是否可以以更好的方式编写 xslt;

我试图在下面展示一个简单的例子。

任何想法或帮助表示赞赏。

输入xml:

<result>
    <program>
        <c i='0' d='Policy'>
            <c i='14' d='LOB'>
                <m i='CR TOT TERR TERM PREM' d='CR TOT TERR TERM PREM' v='-17277' />
                <m i='CR TOT TERR NET PREM' d='CR TOT TERR NET PREM' v='-14935' />
                <m i='CR TOT TERR GAP PREM' d='CR TOT TERR GAP PREM' v='294' />
                <m i='CR TOT TERR FINAL ADJ PREM' d='CR TOT TERR FINAL ADJ PREM'
                    v='-17571' />
                <m i='CR QUOTE OPTION ID' d='CR QUOTE OPTION ID'
                    v='Quote0001' />
                <m i='CR TOT TERR COMMISSION' d='CR TOT TERR COMMISSION' v='-2635.65' />
                <m i='CR TOT TERR ACTUAL PREM' d='CR TOT TERR ACTUAL PREM' v='-17571' />
                <m i='CR TOT TERM PREM' d='CR TOT TERM PREM' v='-881154' />
                <m i='CR TOT TAXES AND SRCHRG' d='CR TOT TAXES AND SRCHRG' v='-892.14' />
                <m i='CR TOT STATE SRCHRG' d='CR TOT STATE SRCHRG' v='-896.14' />
                <m i='CR TOT PREM ADJ' d='CR TOT PREM ADJ' v='0' />
                <m i='CR TOT PREM' d='CR TOT PREM' v='-897026.14' />
                <m i='CR TOT NET PREM' d='CR TOT NET PREM' v='-761713' />
                <m i='CR TOT GAP PREM' d='CR TOT GAP PREM' v='14980' />
                <m i='CR TOT FINAL ADJ PREM' d='CR TOT FINAL ADJ PREM' v='-896134' />
                <m i='CR TOT COMMISSION' d='CR TOT COMMISSION' v='-134420.1' />
                <m i='CR TOT ADDL COV TERM PREM' d='CR TOT ADDL COV TERM PREM' v='-879465' />
                <m i='CR TOT ADDL COV NET PREM' d='CR TOT ADDL COV NET PREM' v='-760253.59999999998' />
                <m i='CR TOT ADDL COV GAP PREM' d='CR TOT ADDL COV GAP PREM' v='14951' />
                <m i='CR TOT ADDL COV FINAL ADJ PREM' d='CR TOT ADDL COV FINAL ADJ PREM'
                    v='-894416' />
                <m i='CR TOT ADDL COV COMMISSION' d='CR TOT ADDL COV COMMISSION'
                    v='-134162.40000000002' />
                <m i='CR TOT ADDL COV ACTUAL PREM' d='CR TOT ADDL COV ACTUAL PREM'
                    v='-894416' />
                <m i='CR TOT ACTUAL PREM' d='CR TOT ACTUAL PREM' v='-896134' />
                <m i='CR STATE SRCHRG NAME' d='CR STATE SRCHRG NAME' v='FL Comml Prop Fire Marshall' />
                <m i='CR FL POLICY SRCHRG NAME' d='CR FL POLICY SRCHRG NAME' v='FL Emergency Mgmt Praparedness' />
                <m i='CR FL POLICY SRCHRG' d='CR FL POLICY SRCHRG' v='4' />
                <m i='CR EMPL THEFT ANNUAL RATE' d='CR EMPL THEFT ANNUAL RATE' v='1.144' />
                <m i='CR EMPL THEFT ANNUAL PREM' d='CR EMPL THEFT ANNUAL PREM' v='15401' />
            </c>
        </c>
    </program>
</result>

xslt:

<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns="urn:company:esb:services:Pricing:v01">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes">
    </xsl:output>
    <xsl:strip-space elements="*"/>
    <xsl:template match="/result/program/c">
        <xsl:element name="pricing-response">
            <dummy>
                <policy>
                    <xsl:for-each select="c">
                        <xsl:variable name='strComp'>
                            <xsl:value-of select='@i'/>
                        </xsl:variable>
                        <xsl:if test="@d ='CrimeLine' ">
                            <policy-output>
                                <xsl:for-each select="m">
                                    <xsl:variable name='strComp'>
                                        <xsl:value-of select='@i'/>
                                    </xsl:variable>
                                    <xsl:if test="$strComp ='CR QUOTE OPTION ID' ">
                                        <quote-option-id>
                                            <xsl:value-of select='@v'/>
                                        </quote-option-id>
                                    </xsl:if>
                                    <xsl:if test="$strComp ='CR TOT TAXES AND SRCHRG' ">
                                        <total-taxsurcharge-amt>
                                            <amount>
                                                <xsl:value-of select='@v'/>
                                            </amount>
                                        </total-taxsurcharge-amt>
                                    </xsl:if>
                                    <xsl:if test="$strComp ='CR TOT PREM' ">
                                        <total-premium-amt>
                                            <amount>
                                                <xsl:value-of select='@v'/>
                                            </amount>
                                        </total-premium-amt>
                                    </xsl:if>
                                </xsl:for-each>
                                <taxsurcharge-summary>
                                    <taxsurcharge>
                                        <taxsurcharge-identifier>State</taxsurcharge-identifier>
                                        <xsl:for-each select="m">
                                            <xsl:variable name='strComp'>
                                                <xsl:value-of select='@i'/>
                                            </xsl:variable>
                                            <xsl:if test="$strComp ='CR TOT STATE SRCHRG' ">
                                                <taxsurcharge-amt>
                                                    <amount>
                                                        <xsl:value-of select='@v'/>
                                                    </amount>
                                                </taxsurcharge-amt>
                                            </xsl:if>
                                            <xsl:if test="$strComp ='CR STATE SRCHRG NAME' ">
                                                <taxsurcharge-name>
                                                    <xsl:value-of select='@v'/>
                                                </taxsurcharge-name>
                                            </xsl:if>
                                            <xsl:if test="$strComp ='CR STATE SRCHRG CODE' ">
                                                <taxsurcharge-code>
                                                    <xsl:value-of select='@v'/>
                                                </taxsurcharge-code>
                                            </xsl:if>
                                        </xsl:for-each>
                                    </taxsurcharge>
                                </taxsurcharge-summary>
                            </policy-output>
                        </xsl:if>
                    </xsl:for-each>
                </policy>
            </dummy>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

输出xml:

<?xml version="1.0" encoding="UTF-8"?>
<pricing-response xmlns="urn:company:esb:services:Pricing:v01">
    <dummy>
        <policy>
            <policy-output>
                <quote-option-id>Quote0001</quote-option-id>
                <total-taxsurcharge-amt>
                    <amount>-892.14</amount>
                </total-taxsurcharge-amt>
                <total-premium-amt>
                    <amount>-897026.14</amount>
                </total-premium-amt>
                <taxsurcharge-summary>
                    <taxsurcharge>
                        <taxsurcharge-identifier>State</taxsurcharge-identifier>
                        <taxsurcharge-amt>
                            <amount>-896.14</amount>
                        </taxsurcharge-amt>
                        <taxsurcharge-name>FL Comml Prop Fire Marshall</taxsurcharge-name>
                    </taxsurcharge>
                </taxsurcharge-summary>
            </policy-output>
        </policy>
    </dummy>
</pricing-response>

标签: xmlxslt

解决方案


实际上,XSLT 的新手,尤其是通用语言的新手,通常将 XML 文档视为可迭代的,其中必须迭代节点for:eachif逻辑以转换原始源。但是,在 XSLT 中,需要考虑模板来重新创建树。

考虑以下情况,您将向下移动到第二c级,然后使用 XPath 调用有条件地检索值。如果没有默认命名空间,脚本会更短,urn:company:esb:services:Pricing:v01在 root 中需要<xsl:element ... namespace=...>在每个新分配的节点上。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output indent="yes" method="xml" version="1.0" encoding="UTF-8"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/result/program/c">
    <pricing-response xmlns="urn:company:esb:services:Pricing:v01">
        <dummy>
            <policy>
                <xsl:apply-templates select="c"/>     
            </policy>
        </dummy>
    </pricing-response>
  </xsl:template>

  <xsl:template match="c">
    <xsl:element name="policy-output" namespace="urn:company:esb:services:Pricing:v01">
      <xsl:element name="quote_option" namespace="urn:company:esb:services:Pricing:v01">
        <xsl:value-of select="m[@i='CR QUOTE OPTION ID']/@v"/>
      </xsl:element>
      <xsl:element name="total-taxsurcharge-amt" namespace="urn:company:esb:services:Pricing:v01">
        <xsl:element name="amount" namespace="urn:company:esb:services:Pricing:v01">
            <xsl:value-of select="m[@i='CR TOT TAXES AND SRCHRG']/@v"/>
        </xsl:element>
      </xsl:element>
      <xsl:element name="total-premium-amt" namespace="urn:company:esb:services:Pricing:v01">
        <xsl:element name="amount" namespace="urn:company:esb:services:Pricing:v01">
            <xsl:value-of select="m[@i='CR TOT PREM']/@v"/>
        </xsl:element>
      </xsl:element>
      <xsl:element name="taxsurcharge-summary" namespace="urn:company:esb:services:Pricing:v01">
        <xsl:element name="taxsurcharge" namespace="urn:company:esb:services:Pricing:v01">
            <xsl:element name="taxsurcharge-identifier" namespace="urn:company:esb:services:Pricing:v01">State</xsl:element>
            <xsl:element name="taxsurcharge-amt" namespace="urn:company:esb:services:Pricing:v01">
                <xsl:element name="amount" namespace="urn:company:esb:services:Pricing:v01">
                    <xsl:value-of select="m[@i='CR TOT STATE SRCHRG']/@v"/>
                </xsl:element>
            </xsl:element>
            <xsl:element name="taxsurcharge-name" namespace="urn:company:esb:services:Pricing:v01">
                <xsl:value-of select="m[@i='CR STATE SRCHRG NAME']/@v"/>
            </xsl:element>
        </xsl:element>
      </xsl:element>
    </xsl:element>
  </xsl:template>

 </xsl:stylesheet>

XSLT 小提琴演示


推荐阅读