Xslt скопировать элемент в существующий или создать новый, если не существует - PullRequest
2 голосов
/ 29 марта 2019

Довольно плохо знаком с преобразованиями в xml, и я застрял (может быть, для вас) в довольно легкой задаче. Давайте предположим, что у нас есть источник:

<root>
  <someValue>123</someValue>
</root>

Должен быть преобразован в:

<root>
 <additional>
   <someValue>123</someValue>
 </additional>
</root>

Но если у нас есть это в качестве источника:

<root>
 <additional>
  <b>something</b>
 </additional>
 <someValue>123</someValue>
</root>

мы должны переместить someValue к существующему дополнительно , т. Е .:

<root>
 <additional>
  <b>something</b>
  <someValue>123</someValue>
 </additional>     
</root>

Имейте в виду, что на уровне a могут быть другие элементы с таким же поведением (перемещено под добавочный ). Хорошо, рабочий пример высоко ценится, но если он сопровождается небольшим описанием того, как он работает, это было бы фантастически (я предпочитаю ловить рыбу, а не просто кормить ее).

Ответы [ 4 ]

2 голосов
/ 29 марта 2019

Один из возможных подходов - добавить обертку additional в качестве дочернего элемента root и удалить существующую обертку additional, чтобы ее дочерние элементы переместились вверх, чтобы стать потомками root (или, скорее, потомкамидобавлена ​​additional оболочка):

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="/root">
    <xsl:copy>
        <additional>
            <xsl:apply-templates/>
        </additional>
    </xsl:copy>
</xsl:template>

<xsl:template match="additional">
    <xsl:apply-templates/>
</xsl:template>

</xsl:stylesheet>
1 голос
/ 29 марта 2019

Имейте в виду, что на уровне a могут быть другие элементы с таким же поведением (перемещено под additional).

Эта таблица стилей:

<xsl:stylesheet version="1.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[additional|someValue]">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <additional>
                <xsl:apply-templates select="additional/*|someValue"/>
            </additional>
            <xsl:apply-templates select="node()[not(self::additional|self::someValue)]"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

С этим входом:

<root>
    <additional>
        <b>something</b>
    </additional>
    <someValue>123</someValue>
    <anotherValue>keep</anotherValue>
</root>

Выход:

<root>
    <additional>
        <b>something</b>
        <someValue>123</someValue>
    </additional>
    <anotherValue>keep</anotherValue>
</root>

Примечание : только одно правило для переопределения преобразования идентификаторов.Только процесс root, удовлетворяющий условиям (someValue или additional childs).Копирование root, применение шаблонов к атрибутам (для дальнейшей обработки), перенос элемента additional в результате применения шаблонов к дочерним элементам additional и someValue дочерним элементам.Наконец, применение шаблонов к дочерним элементам root, которые не являются ни additional, ни someValue.

0 голосов
/ 30 марта 2019

Использовать для версии xslt 2.0

    <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:output method="xml" omit-xml-declaration="no" indent="yes"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node() except someValue"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="additional">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
            <xsl:copy-of select="following-sibling::someValue"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
0 голосов
/ 29 марта 2019

Я получил следующее:

<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="/root/additional"/>

<xsl:template match="/root">
    <xsl:copy>
        <additional>
            <xsl:copy-of select="someValue"/>
            <xsl:copy-of select="additional/*"/>
        </additional>
    </xsl:copy>
</xsl:template>

Здесь мы удаляем оригинал дополнительно , а затем создаем его с нуля, где необходимо someValue и исходный контент из источника ( extra / *)

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