XSLT, чтобы обернуть последующие элементы родного брата, в зависимости от количества - PullRequest
3 голосов
/ 21 сентября 2011

Я пытаюсь выяснить xslt, который должен быть довольно простым, но вызывает у меня некоторое горе. По сути, я хотел бы начать со следующего xml ...

<?xml version="1.0" encoding="UTF-8"?>
<TEST>
    <OBR>
        <OBR-1>obr1</OBR-1>
    </OBR>
    <OBX>
        <OBX-1>obx1</OBX-1>
    </OBX>
    <OBX>
        <OBX-1>obx2</OBX-1>
    </OBX>
    <OBR>
        <OBR-1>obr2</OBR-1>
    </OBR>
    <OBX>
        <OBX-1>obx2-1</OBX-1>
    </OBX>
    <OBX>
        <OBX-1>obx2-2</OBX-1>
    </OBX>
    <OBR>
        <OBR-1>obr3</OBR-1>
    </OBR>
    <OBX>
        <OBX-1>obx3-1</OBX-1>
    </OBX>
    <OBX>
        <OBX-1>obx3-2</OBX-1>
    </OBX>
</TEST>

и в итоге получим следующее ...

<?xml version="1.0" encoding="UTF-8"?>
<TEST>
    <OBR>
        <OBR-1>obr1</OBR-1>
    </OBR>
    <OBX>
        <OBX-1>obx1</OBX-1>
    </OBX>
    <OBX>
        <OBX-1>obx2</OBX-1>
    </OBX>
    <SENSITIVITY>
        <OBR>
            <OBR-1>obr2</OBR-1>
        </OBR>
        <OBX>
            <OBX-1>obx2-1</OBX-1>
        </OBX>
        <OBX>
            <OBX-1>obx2-2</OBX-1>
        </OBX> 
        <OBR>
            <OBR-1>obr3</OBR-1>
        </OBR>
        <OBX>
            <OBX-1>obx3-1</OBX-1>
        </OBX>
        <OBX>
            <OBX-1>obx3-2</OBX-1>
        </OBX>
    </SENSITIVITY>
</TEST>

По сути, как только будет достигнут второй элемент OBR, он и все последующие OBR и OBX должны быть включены в элемент SENSITIVITY. Исходный xml может содержать или не содержать более одного OBR.

Спасибо.

1 Ответ

3 голосов
/ 21 сентября 2011

Это простое и короткое преобразование :

<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()|@*" name="identity">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="OBR[2]">
  <SENSITIVITY>
   <xsl:apply-templates select=".|following-sibling::node()" mode="inGroup"/>
  </SENSITIVITY>
 </xsl:template>

 <xsl:template match="node()" mode="inGroup">
  <xsl:call-template name="identity"/>
 </xsl:template>

 <xsl:template match="*[count(preceding-sibling::OBR) >1]"/>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<TEST>
    <OBR>
        <OBR-1>obr1</OBR-1>
    </OBR>
    <OBX>
        <OBX-1>obx1</OBX-1>
    </OBX>
    <OBX>
        <OBX-1>obx2</OBX-1>
    </OBX>
    <OBR>
        <OBR-1>obr2</OBR-1>
    </OBR>
    <OBX>
        <OBX-1>obx2-1</OBX-1>
    </OBX>
    <OBX>
        <OBX-1>obx2-2</OBX-1>
    </OBX>
    <OBR>
        <OBR-1>obr3</OBR-1>
    </OBR>
    <OBX>
        <OBX-1>obx3-1</OBX-1>
    </OBX>
    <OBX>
        <OBX-1>obx3-2</OBX-1>
    </OBX>
</TEST>

дает желаемый, правильный результат :

<TEST>
   <OBR>
      <OBR-1>obr1</OBR-1>
   </OBR>
   <OBX>
      <OBX-1>obx1</OBX-1>
   </OBX>
   <OBX>
      <OBX-1>obx2</OBX-1>
   </OBX>
   <SENSITIVITY>
      <OBR>
         <OBR-1>obr2</OBR-1>
      </OBR>
      <OBX>
         <OBX-1>obx2-1</OBX-1>
      </OBX>
      <OBX>
         <OBX-1>obx2-2</OBX-1>
      </OBX>
      <OBR>
         <OBR-1>obr3</OBR-1>
      </OBR>
      <OBX>
         <OBX-1>obx3-1</OBX-1>
      </OBX>
      <OBX>
         <OBX-1>obx3-2</OBX-1>
      </OBX>
   </SENSITIVITY>
</TEST>

Объяснение

  1. Правило идентификации копирует каждый узел "как есть".

  2. Шаблон переопределяет правило идентификации для элемента OBR, который является вторым дочерним элементом OBR его родителя. Здесь мы генерируем элемент оболочки SENSITIVITY и обрабатываем все последующие узлы в специальном режиме с именем "inGroup".

  3. Шаблон, соответствующий любому элементу в режиме "ingroup", просто вызывает правило идентификации. Кроме того, здесь мы могли бы просто использовать инструкцию <xsl:copy-of select="."/>.

  4. Чтобы подавить копирование шаблона идентификации на выход (в обычном анонимном режиме) элементов, следующих за вторым OBR, мы указываем другое правило шаблона, которое соответствует любому такому элементу и имеет пустое тело, которое эффективно предотвращает копирование любого такого элемента на выход. Этот шаблон переопределяет и подавляет правило идентификации.

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