Nano Hash - криптовалюты, майнинг, программирование

Как применить несколько определений шаблонов, каждое из которых изменяет одну и ту же структуру XML

В этом примере кода у меня есть 2 задачи: одна - установить узел B1 после узла B и перед узлами C, D и E, а вторая задача - добавить второй узел KEY в структуру / ROOT / E / OTHER / DEAL / KEYS.

Этот образец XML:

        <ROOT>
          <A>some A text</A>
          <B>some B text</B>
          <C>some C text</C>
          <D>some D text</D>
          <E>
            <OTHER>
              <DEAL>
                <KEYS>
                  <KEY>
                    <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType>
                    <KeyValue>123456|1</KeyValue>
                  </KEY>
                </KEYS>
              </DEAL>
            </OTHER>
          </E>
        </ROOT>

после преобразования:

    <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <xsl:strip-space elements="*"/>
        <xsl:output method="xml" indent="yes"/>

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

        <!-- Identifiers are added by the system. Need to pass parms from the calling program -->
        <xsl:template match="ROOT" name="add-B1">
            <xsl:variable name="elements-after" select="C|D|E"/>
            <xsl:copy>
                <xsl:copy-of select="* except $elements-after"/>
                <B1>some B1 text</B1>
                <xsl:copy-of select="$elements-after"/>
            </xsl:copy>
        </xsl:template>

        <!-- KEY is added by the system. Need to pass parms from the calling program -->
        <xsl:template match="ROOT/E/OTHER/DEAL/KEYS" name="add-KEYS">
            <xsl:param name="KeyIdentifierTypeB">654321|1</xsl:param>
            <xsl:copy>
                <xsl:copy-of select="*"/>
                <KEY>
                    <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType>
                    <KeyValue>
                        <xsl:value-of select="$KeyIdentifierTypeB"/>
                    </KeyValue>
                </KEY>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>

стали:

        <?xml version="1.0" encoding="UTF-8"?>
        <ROOT>
            <A>some A text</A>
            <B>some B text</B>
            <B1 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">some B1 text</B1>
            <C>some C text</C>
            <D>some D text</D>
            <E>
                <OTHER>
                    <DEAL>
                        <KEYS>
                            <KEY>
                                <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType>
                                <KeyValue>123456|1</KeyValue>
                            </KEY>
                        </KEYS>
                    </DEAL>
                </OTHER>
            </E>
        </ROOT>

почему второе определение шаблона было полностью проигнорировано?

Первый кодовый колледж был разрешен. Узел B1 устанавливается после узла B и перед узлами C, D и E, или, другими словами, установлен узел B1, а после него должны стоять узлы: C, D и E.
Второй шаблон match = «ROOT / E / OTHER / DEAL / KEYS», который должен удовлетворять второй части задачи: добавить второй узел KEY в структуру / ROOT / E / OTHER / DEAL / KEYS, был полностью проигнорирован. В дополнение к этому факту, если вы прокомментируете первое совпадение шаблона над узлом ROOT, второе совпадение шаблона = "ROOT / E / OTHER / DEAL / KEYS" будет работать правильно, оно фактически добавит дополнительный ключ, но я не Я не знаю, почему первое совпадение с шаблоном всегда имеет приоритет над вторым. Я пробую xsl: template match = "ROOT / E / OTHER / DEAL / KEYS ... и xsl: for-each select = ... и xsl: call-template name =" add-KEYS ", но мне ничего не помогло из.

Я действительно понимаю, что apply-templates соответствуют шаблонам узлов с более высокой структурой с наивысшим приоритетом. Изменение места шаблона в XSLT-файле никак не повлияет, он не будет читать его в точной последовательности строк, вместо этого он будет обрабатывать его с сопоставлением приоритета. «Apply-templates» для каждого совпадающего шаблона внесет изменения в структуру XML, неявно он сделает «для каждого» для нас, но я не знаю, как «посоветовать» второму шаблону, что структура была изменена , и почему я должен это сделать, потому что второе совпадение с шаблоном ищет другое местоположение XPath, это, кстати, никогда не было затронуто из первого шаблона. Должен ли я применять последовательность шаблонов в моем случае? ... и как лучше всего это сделать?

Ожидаемый результат:

        <?xml version="1.0" encoding="UTF-8"?>
        <ROOT>
            <A>some A text</A>
            <B>some B text</B>
            <B1>some B1 text</B1>
            <C>some C text</C>
            <D>some D text</D>
            <E>
                <OTHER>
                    <DEAL>
                        <KEYS>
                            <KEY>
                                <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType>
                                <KeyValue>123456|1</KeyValue>
                            </KEY>
                            <KEY>
                                <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType>
                                <KeyValue>654321|1</KeyValue>
                            </KEY>
                        </KEYS>
                    </DEAL>
                </OTHER>
            </E>
        </ROOT>
24.08.2012

Ответы:


1

Второй шаблон match="ROOT/E/OTHER/DEAL/KEYS", который должен удовлетворять второй части задачи: добавить второй узел KEY в структуру /ROOT/E/OTHER/DEAL/KEYS, был полностью проигнорирован.

Проблема в том, что в совпадающем шаблоне ROOT нет никакого xsl:apply-templates. Шаблон выбирается для выполнения только в результате инструкции xsl:apply-templates. В вашем коде нет xsl:apply-templates, поэтому XSLT-процессор больше не применяет шаблоны и завершает выполнение.

Было бы иначе, если бы вы заменили xsl:copy-of на xsl:apply-templates.

Вот как это сделать:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="/*">
  <xsl:copy>
    <xsl:apply-templates select="@*|B/preceding-sibling::node()"/>
    <xsl:apply-templates select="B"/>
    <B1>some B1 text</B1>
    <xsl:apply-templates select="B/following-sibling::node()"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="KEY">
  <xsl:copy>
   <xsl:apply-templates select="@*|node()"/>
   <KEY>
    <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType>
    <KeyValue>
     <xsl:value-of select="'654321|1'"/>
    </KeyValue>
   </KEY>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

Когда это преобразование применяется к предоставленному XML-документу:

<ROOT>
    <A>some A text</A>
    <B>some B text</B>
    <C>some C text</C>
    <D>some D text</D>
    <E>
        <OTHER>
            <DEAL>
                <KEYS>
                    <KEY>
                        <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType>
                        <KeyValue>123456|1</KeyValue>
                    </KEY>
                </KEYS>
            </DEAL>
        </OTHER>
    </E>
</ROOT>

Получен желаемый правильный результат:

<ROOT>
   <A>some A text</A>
   <B>some B text</B>
   <B1>some B1 text</B1>
   <C>some C text</C>
   <D>some D text</D>
   <E>
      <OTHER>
         <DEAL>
            <KEYS>
               <KEY>
                  <KeyIdentifierType>KeyIdentifierTypeA</KeyIdentifierType>
                  <KeyValue>123456|1</KeyValue>
                  <KEY>
                     <KeyIdentifierType>KeyIdentifierTypeB</KeyIdentifierType>
                     <KeyValue>654321|1</KeyValue>
                  </KEY>
               </KEY>
            </KEYS>
         </DEAL>
      </OTHER>
   </E>
</ROOT>
24.08.2012
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..