使用XLST复制/粘贴前一个元素的值

时间:2019-06-13 17:48:48

标签: xslt

我有以下XML:

<?xml version="1.0"?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<database name="ims_prod">
<table_data name="wp_trp_dictionary_en_us_de_de">
<row>
<field name="id">1</field>
<field name="original">Random text 1</field>
<field name="translated"></field>
<field name="status">0</field>
<field name="block_type">0</field>
</row>
<row>
<field name="id">2</field>
<field name="original">Random text 2</field>
<field name="translated"></field>
<field name="status">0</field>
<field name="block_type">0</field>
</row>
</table_data>
</database>
</mysqldump>

我需要复制每个具有“原始”属性的节点的值,并将其粘贴到以下同级(具有“ translated”属性的同级中。)

预期:

<?xml version="1.0"?>
<mysqldump xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<database name="ims_prod">
<table_data name="wp_trp_dictionary_en_us_de_de">
<row>
<field name="id">1</field>
<field name="original">Random text 1</field>
<field name="translated">**Random text 1**</field>
<field name="status">0</field>
<field name="block_type">0</field>
</row>
<row>
<field name="id">2</field>
<field name="original">Random text 2</field>
<field name="translated">**Random text 2**</field>
<field name="status">0</field>
<field name="block_type">0</field>
</row>
</table_data>
</database>
</mysqldump>

我尝试了以下XSLT:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:com="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="//table_data/row/field[@name='original']/text()">
      <xsl:value-of select="//table_data/row/field[@name='original']/following-sibling::field[@name='translated']"/>
  </xsl:template>
</xsl:stylesheet>

但是它会清空所有具有“原始”属性的节点。

我在做什么错?谢谢您的帮助!

2 个答案:

答案 0 :(得分:1)

您要更改translated字段的值,因此需要使模板与之匹配。如果该字段为空,则匹配其文本节点将不起作用。

请尝试:

XSLT 1.0

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

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

<xsl:template match="field[@name='translated']">
    <field name="translated">
        <xsl:value-of select="preceding-sibling::field[@name='original']"/>
    </field>
</xsl:template>

</xsl:stylesheet>

P.S。注意在select="preceding-sibling::field[@name='original']"中使用相对路径。您的版本将始终选择第一行的原始内容。

答案 1 :(得分:1)

您可以使用以下模板来获得所需的结果:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:com="http://www.w3.org/2001/XMLSchema-instance">
    <xsl:output method="xml" indent="yes"/>

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

  <xsl:template match="table_data/row/field[@name='translated']">
    <xsl:copy>
      <xsl:copy-of select="@*" />
      <xsl:value-of select="concat('**',preceding-sibling::field[1]/text(),'**')"/>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

输出符合预期。