XSLT: возможно ли слепо пропускать большинство элементов, но при этом трансформировать определенные элементы? - PullRequest
0 голосов
/ 19 сентября 2018

При наличии xml-файла, содержащего элементы a, b, c и d, можно ли написать XSLT, который будет изменять только элемент "c" и пропускать вслепую все остальные элементы?

Например:

<?xml version="1.0" encoding="UTF-8"?>
<Person>
    <a>pass me blindly</a>
    <b>pass me blindly</b>
    <c>I need XSLT to convert me</c>
    <d>pass me blindly</d>
</Person>

Возможно ли иметь XSLT, который выполняет преобразование "c", и все же все другие элементы передаются, как они есть в источнике?

Я бы закончил с:

<?xml version="1.0" encoding="UTF-8"?>
<Person>
    <a>pass me blindly</a>
    <b>pass me blindly</b>
    <c>I've been CONVERTED!</c>
    <d>pass me blindly</d>
</Person>

И да, мой уровень знаний по XSLT ограничен.

Ответы [ 3 ]

0 голосов
/ 19 сентября 2018

У вас есть две возможности для достижения желаемого:

  • подход WhiteList и
  • подход BlackList

Первая копирует всеузлы, за исключением занесенных в белый список, которые обрабатываются по-разному:

<?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" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />

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

  <xsl:template match="c">
    <xsl:value-of select="concat('The node ',name(),' is being processed.')" />
  </xsl:template>  

</xsl:stylesheet>

Второй копирует только узлы, занесенные в черный список, которые не должны обрабатываться дальше:

<?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" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />

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

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

  <xsl:template match="*[parent::Person]" priority="0">
    <xsl:value-of select="concat('The node ',name(),' is being processed.')" />
  </xsl:template>   

</xsl:stylesheet>
0 голосов
/ 20 сентября 2018

Поскольку вы упоминаете Altova, вы также можете использовать XSLT 3 (если у вас есть текущая версия Altova), а в XSLT 3 вы можете использовать xsl:mode on-no-match с другими значениями on-no-match? = "deep-copy" | "shallow-copy" | "deep-skip" | "shallow-skip" | "text-only-copy" | "fail", см. https://www.w3.org/TR/xslt-30/#built-in-rule и https://www.w3.org/TR/xslt-30/#declaring-modes, объявление

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

установит преобразование идентичности как встроенные правила для безымянного режима.Тогда вам нужно будет только добавить шаблон для того элемента, который вы хотите преобразовать.

0 голосов
/ 19 сентября 2018
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<?xml-stylesheet type="text/xml" href=".\XSLTFile1.xslt"?>
 <Person >
  <a>pass me blindly</a>
  <b>pass me blindly</b>
  <c>I need XSLT to convert me</c>
  <d>pass me blindly</d>
</Person>

Следующий шаблон XSL-преобразования даст желаемый результат

<?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" version="1.0" encoding="UTF-8" indent="yes" omit-xml-declaration="yes" />
  <xsl:template match="xsl:stylesheet" />
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="c">
    <c>I've been CONVERTED!</c>
  </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...