Копировать / вставить значение предыдущего элемента с помощью XLST - PullRequest
0 голосов
/ 13 июня 2019

У меня есть следующий 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>

Мне нужно скопировать значение каждого узла, имеющего атрибут «original», и вставить его в следующий брат (сестра, у которой есть атрибут «translation».

Ожидается:

<?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 ]

1 голос
/ 13 июня 2019

Вы можете использовать эти шаблоны для получения желаемого результата:

<?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>

Вывод соответствует ожидаемому.

1 голос
/ 13 июня 2019

Вы хотите изменить значение поля 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>

PS Обратите внимание на использование относительного пути в select="preceding-sibling::field[@name='original']".Ваша версия всегда будет выбирать оригинал первого ряда.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...