Xml 带属性的XSLT转换

Xml 带属性的XSLT转换,xml,xslt,xslt-1.0,Xml,Xslt,Xslt 1.0,我需要基于XML中的属性进行xslt转换。对于所有具有ed Cover的属性,我需要在目标XML中创建coverage标记,并将元素作为子元素映射到其中。您能帮助我吗 输入XML: <c> <m p='ed-Cover'></m> <m p='premum-amt' v='100'></m> <m p='premium-rate' v='10'></m> <m p='prem-date' v='10-04-

我需要基于XML中的属性进行xslt转换。对于所有具有ed Cover的属性,我需要在目标XML中创建coverage标记,并将元素作为子元素映射到其中。您能帮助我吗

输入XML:

<c>
<m p='ed-Cover'></m>
<m p='premum-amt' v='100'></m>
<m p='premium-rate' v='10'></m>
<m p='prem-date' v='10-04-15'></m>
<m p='ed-Cover'></m>
<m p='premum-amt' v='50'></m>
<m p='premium-rate' v='5'></m>
<m p='prem-date' v='12-03-15'></m>
<m p='ed-Cover'></m>
<m p='premum-amt' v='75'></m>
<m p='premium-rate' v='7'></m>
<m p='prem-date' v='3-05-15'></m>
</c>

XSLT:


预期产出:

<coverages>
<coverage>
<coverage-prem-amt>100</coverage-prem-amt>
<coverage-prem-rate>10</coverage-prem-rate>
<coverage-prem-date>10-04-15</coverage-prem-date>
</coverage>
<coverage>
<coverage-prem-amt>50</coverage-prem-amt>
<coverage-prem-rate>5</coverage-prem-rate>
<coverage-prem-date>12-03-15</coverage-prem-date>
</coverage>
<coverage>
<coverage-prem-amt>75</coverage-prem-amt>
<coverage-prem-rate>7</coverage-prem-rate>
<coverage-prem-date>3-05-15</coverage-prem-date>
</coverage>
<coverages>

100
10
10-04-15
50
5.
12-03-15
75
7.
3-05-15

由于您希望
m
元素的
coverage
元素具有“ed Cover”作为属性值,您应该将
xsl:for each
更改为

  <xsl:for-each select="c/m[@p='ed-Cover']">

要获取所需的值(即此元素的同级),可能需要有一个键,以便您可以根据前面的第一个“ed Cover”查找其他元素

<xsl:key name="cover" match="m" use="generate-id(preceding-sibling::m[@p='ed-Cover'][1])" />

因此,要获得当前“ed保险”的保险费金额,您可以这样做

 <xsl:variable name="id" select="generate-id()" />

 <coverage-prem-amt>
    <xsl:value-of select="key('cover', $id)[@p='premum-amt']/@v" />
 </coverage-prem-amt>

试试这个XSLT

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

  <xsl:key name="cover" match="m" use="generate-id(preceding-sibling::m[@p='ed-Cover'][1])" />

  <xsl:template match="/">
    <coverages>
      <xsl:for-each select="c/m[@p='ed-Cover']">
        <xsl:variable name="id" select="generate-id()" />
         <coverage>
           <coverage-prem-amt>
             <xsl:value-of select="key('cover', $id)[@p='premum-amt']/@v" />
           </coverage-prem-amt>
           <coverage-prem-rate>
             <xsl:value-of select="key('cover', $id)[@p='premium-rate']/@v" />
           </coverage-prem-rate>
           <coverage-prem-date>
             <xsl:value-of select="key('cover', $id)[@p='prem-date']/@v" />
           </coverage-prem-date>
         </coverage>
      </xsl:for-each>
    </coverages>
  </xsl:template>
</xsl:stylesheet>

编辑:如果不希望在值不存在时创建元素,请尝试使用模板方法

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

  <xsl:key name="cover" match="m" use="generate-id(preceding-sibling::m[@p='ed-Cover'][1])" />

  <xsl:template match="/">
    <coverages>
      <xsl:for-each select="c/m[@p='ed-Cover']">
        <xsl:variable name="id" select="generate-id()" />
         <coverage>
           <xsl:apply-templates select="key('cover', $id)[@p='premum-amt']" />
           <xsl:apply-templates select="key('cover', $id)[@p='premium-rate']" />
           <xsl:apply-templates select="key('cover', $id)[@p='prem-date']" />
         </coverage>
      </xsl:for-each>
    </coverages>
  </xsl:template>

  <xsl:template match="m[@p='premum-amt']">
    <coverage-prem-amt>
      <xsl:value-of select="@v" />
    </coverage-prem-amt>
  </xsl:template>  

  <xsl:template match="m[@p='premium-rate']">
    <coverage-prem-rate>
      <xsl:value-of select="@v" />
    </coverage-prem-rate>
  </xsl:template>

  <xsl:template match="m[@p='prem-date']">
    <coverage-prem-date>
      <xsl:value-of select="@v" />
    </coverage-prem-date>
  </xsl:template>
</xsl:stylesheet>

这也可以:

  <xsl:template match="c">
    <xsl:element name="coverages">
      <xsl:apply-templates select="m[@p='premum-amt']"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="m[@p='premum-amt']">
    <xsl:element name="coverage">
      <xsl:element name="coverage-prem-amt">
        <xsl:value-of select="@v"/>
      </xsl:element>
      <xsl:element name="coverage-prem-rate">
        <xsl:value-of select="following-sibling::m[@p='premium-rate'][1]/@v"/>
      </xsl:element>
      <xsl:element name="coverage-prem-date">
        <xsl:value-of select="following-sibling::m[@p='prem-date'][1]/@v"/>
      </xsl:element>
    </xsl:element>
  </xsl:template>


对于每个
ed保险,XML中是否始终存在
保费金额
保费率
保费日期
?Hi-Tim仅当它存在时是可选的。我需要创建保费金额、保费率和保费日期并映射它。还请注意保费金额的元素,保险费率和保险日期不在ed-Cover内。这是我所期望的,非常感谢Tim的快速响应
  <xsl:template match="c">
    <xsl:element name="coverages">
      <xsl:apply-templates select="m[@p='premum-amt']"/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="m[@p='premum-amt']">
    <xsl:element name="coverage">
      <xsl:element name="coverage-prem-amt">
        <xsl:value-of select="@v"/>
      </xsl:element>
      <xsl:element name="coverage-prem-rate">
        <xsl:value-of select="following-sibling::m[@p='premium-rate'][1]/@v"/>
      </xsl:element>
      <xsl:element name="coverage-prem-date">
        <xsl:value-of select="following-sibling::m[@p='prem-date'][1]/@v"/>
      </xsl:element>
    </xsl:element>
  </xsl:template>