Добавить элемент между двумя другими элементами через XSLT?

У меня есть следующий входной XML:

<root>
    <aaa>some string aaa</aaa>
    <bbb>some string bbb</bbb>
    <ddd>some string ddd</ddd> 
</root>

Используя XSLT, я хочу получить следующий результат:

<root>
    <aaa>some string aaa</aaa>
    <bbb>some string bbb</bbb>
    <ccc>some string ccc</ccc>
    <ddd>some string ddd</ddd>
</root>

Мой XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="root">
        <root>
            <ccc>some string ccc</ccc>
            <xsl:apply-templates select="@*|node()"/> 
        </root>
    </xsl:template>
</xsl:stylesheet>

Но я не получаю желаемого результата. Как я могу поместить элемент ccc между элементами bbb и ddd, используя шаблон удостоверения?

Я могу использовать XSLT 3.0, если это поможет.


person Frank huaylinos velasquez    schedule 06.10.2017    source источник
comment
Здесь вам не нужен XSLT 3.0 - достаточно XSLT 1.0.   -  person kjhughes    schedule 07.10.2017


Ответы (2)


Ответ Кеннета в порядке, но поскольку вопрос помечен как XSLT 3.0, его можно написать более компактно, поэтому я добавляю этот ответ в качестве альтернативы

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="3.0">

    <xsl:output indent="yes"/>

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:template match="ddd">
        <ccc>some string ccc</ccc>
        <xsl:next-match/>
    </xsl:template>

</xsl:stylesheet>

использование <xsl:mode on-no-match="shallow-copy"/> для выражения преобразования идентичности и использование <xsl:next-match/> для делегирования ему копирования элемента ddd.

person Martin Honnen    schedule 07.10.2017
comment
Очень приятно увидеть для сравнения решение XSLT 3.0. - person kjhughes; 07.10.2017

Используйте преобразование идентичности со вторым шаблоном, который соответствует элементу до или после точки вставки, а затем вставьте новый элемент после или перед копированием поверх совпадающего элемента. А именно:

Учитывая этот входной XML,

<root>
   <aaa>some string aaa</aaa>
   <bbb>some string bbb</bbb>
   <ddd>some string ddd</ddd> 
</root>

этот XSLT,

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes"/>

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

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

</xsl:stylesheet>

сгенерирует этот выходной XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <aaa>some string aaa</aaa>
   <bbb>some string bbb</bbb>
   <ccc>some string ccc</ccc>
   <ddd>some string ddd</ddd> 
</root>
person kjhughes    schedule 06.10.2017