Замените узлы xml с помощью xslt - PullRequest
0 голосов
/ 07 апреля 2019

В этом xml я хочу заменить узел <transfom> другим узлом <message>, но скопировать данные.

Возможно ли с xslt, я использовал xslt 2.0, чтобы преобразовать узел преобразования вузел сообщения, но он работает только для одного узла потока.

<root
    xmlns="http://www.example.com/something">
    <flow>
        <list name="listName"/>
        <router name="router"/>
        <!-- I have some other tags here -->
    </flow>
    <flow>
        <list name="listName"/>
        <console name="console"/>
        <!-- I have some other tags here -->
    </flow>
    <flow>
        <payload name="example"/>
        <transform name="transform">
            <!-- Some DATA here --->
        </transform>
        <!-- I have some other tags here -->
    </flow>
    <flow>
        <payload name="sada"/>
        <transform name="transform1">
            <!-- Some DATA here --->
        </transform>
        <!-- I have some other tags here -->
        <transform name="transform2">
            <!-- Some DATA here --->
        </transform>
    </flow>
</root>

Узлы <transform> присутствуют в двух узлах <flow>.Есть ли способ написать общий XSLT, чтобы заменить <transform> на <message> узел, сохраняя положение узлов и данных внутри узлов.

Я использовал <xsl:for-each> и <xsl:when>и выражения xpath, такие как предыдущий, следующий.Но они только конвертируют <transform name="transform node">, но копируют все остальные узлы xml как есть.Пожалуйста, дайте мне знать, как решить эту проблему!


Обновление

Это таблица стилей, которую я использовал для преобразования xml

<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <root>
        <xsl:for-each select="flow">
            <xsl:choose>
                <xsl:when test="descendant-or-self::transform">
                    <message>
                        <xsl:attribute name="doc:name">
                            <xsl:value-of
                                        select="//transform/@name" />
                        </xsl:attribute>
                        <ee:message>
                            <ee:set-payload>
                                <xsl:value-of select="payload" />
                            </ee:set-payload>
                        </ee:message>
                    </ee:transform>
                </xsl:when>
            </xsl:choose>
        </xsl:for-each>
    </root>
</xsl:stylesheet>

Обновление 14/04/2019

Как изменить пространства имен из тега <root>?У меня есть куча пространств имен, которые нужно изменить при преобразовании.Как это сделать?

1 Ответ

0 голосов
/ 07 апреля 2019

Проект преобразования должен начинаться с преобразования идентификаторов (см. Раздел «Пример: преобразование идентификаторов» в https://www.w3.org/TR/xslt20/#element-copy), а затем только добавлять шаблоны для узлов, которые вы хотите преобразовать, в XSLT 3 вы можете объявитьпреобразование идентичности в качестве обработки по умолчанию с использованием <xsl:mode on-no-match="shallow-copy"/> (https://www.w3.org/TR/xslt-30/#built-in-templates-shallow-copy), и тогда вам просто нужно написать шаблон для элементов transform:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xpath-default-namespace="http://www.example.com/something"
    xmlns="http://www.example.com/something"
    exclude-result-prefixes="#all"
    version="3.0">

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

  <xsl:template match="flow/transform">
      <message>
          <xsl:apply-templates select="@*, node()"/>
      </message>
  </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / pPzifpw

в XSLT 2 вы должны прописать это:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xpath-default-namespace="http://www.example.com/something"
    xmlns="http://www.example.com/something"
    exclude-result-prefixes="#all"
    version="2.0">

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

  <xsl:template match="flow/transform">
      <message>
          <xsl:apply-templates select="@*, node()"/>
      </message>
  </xsl:template>

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