编码嵌入在自由文本中的元素的属性

时间:2014-09-03 09:42:04

标签: xslt xpath

我有以下XML,并希望删除所有ele标签,然后对其中某些ele标签中的ph元素的x属性进行编号:

  <?xml version="1.0" encoding="UTF-8"?>
   <tmx version="1.4">
 <body>
    <tu>
        <prop type="x-Context">-2050338055591740051, -2050338055591740051</prop>
        <prop type="x-Origin">TM</prop>
        <prop type="x-ConfirmationLevel">Translated</prop>
        <tuv>
            <seg>
                <ele>The text </ele>
                <ele>
                    <ph x="0" type="QIAsymphony"/>
                </ele>
                <ele> goes </ele>
                <ele>
                    <ph x="0" type="470"/>
                </ele>
                <ele> here </ele>
                <ele>
                    <ph x="0" type="471"/>
                </ele>
                <ele>.</ele>
            </seg>
        </tuv>
        <tuv>
            <seg>
                <ele>El texto </ele>
                <ele>
                    <ph x="0" type="QIAsymphony"/>
                </ele>
                <ele> se mete </ele>
                <ele>
                    <ph x="0" type="471"/>
                </ele>
                <ele> aquí </ele>
                <ele>
                    <ph x="0" type="470"/>
                </ele>
                <ele>.</ele>
            </seg>
        </tuv>
    </tu>
 </body>
  </tmx>

我有以下XSLT,它执行编号操作,虽然我不确定在从XML中删除此元素后,要替换缺少的ele标记会做出哪些更改:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
 <xsl:output method="xml" indent="yes" />

 <xsl:key name="ph" match="tuv[1]/seg/ele/ph" use="@type" />

 <xsl:strip-space elements="*" />

 <xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
 </xsl:template>

 <xsl:template match="tuv/seg/ele/ph/@x">
    <xsl:attribute name="x">
        <xsl:value-of select="count(key('ph', ../@type)/../preceding-sibling::ele[ph]) + 1" />
    </xsl:attribute>
</xsl:template>
</xsl:stylesheet>

期望的输出:

<tuv>
    <seg>The text 
        <ph x="1" type="QIAsymphony"/> 
        goes 
        <ph x="3" type="471"/> 
        here 
        <ph x="2" type="470"/>
        . 
    </seg>
</tuv>

1 个答案:

答案 0 :(得分:3)

在评论中,您说要删除<ele>元素,而不删除其内容。

因为您的XSLT已经基于身份转换,所以可以通过添加一个非常简单的模板轻松完成:

<xsl:template match="ele">
  <xsl:apply-templates select="@*|node()" />
</xsl:template>

此模板只读为:“遇到<ele>时,除了处理其子项”之外,不要输出任何内容。实际上<ele>已从输出中删除,其子项仍然存在。

在上下文中:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
  <xsl:output method="xml" indent="yes" />

  <xsl:key name="ph" match="tuv[1]/seg/ele/ph" use="@type" />

  <xsl:strip-space elements="*" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ele">
    <xsl:apply-templates select="@*|node()" />
  </xsl:template>

  <xsl:template match="tuv/seg/ele/ph/@x">
    <xsl:attribute name="x">
      <xsl:value-of select="count(key('ph', ../@type)/../preceding-sibling::ele[ph]) + 1" />
    </xsl:attribute>
  </xsl:template>
</xsl:stylesheet>

结果:

<tmx version="1.4">
  <body>
    <tu>
      <prop type="x-Context">-2050338055591740051, -2050338055591740051</prop>
      <prop type="x-Origin">TM</prop>
      <prop type="x-ConfirmationLevel">Translated</prop>
      <tuv>
        <seg>The text <ph x="1" type="QIAsymphony"/> goes <ph x="2" type="470"/> here <ph x="3" type="471"/>.</seg>
      </tuv>
      <tuv>
        <seg>El texto <ph x="1" type="QIAsymphony"/> se mete <ph x="3" type="471"/> aquí <ph x="2" type="470"/>.</seg>
      </tuv>
    </tu>
  </body>
</tmx>