开发者

XSLT to wrap subsequent sibling elements, depending on count

I'm trying to figure out an xslt that should be fairly simple, but is giving me some grief. Basically, I'd like to start with the following 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>

and end up with the following...

<?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>

Basically, as soon as a second OBR element is reached, it, and any following OBR's and OBX's must be wrapped in the SENSITIVITY element. The initial xml may or may not have more than one OBR's in it.

Thanks.


This simple and short transformation:

<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>

when applied on the provided XML document:

<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>

produces the wanted, correct result:

<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>

Explanation:

  1. The identity rule copies every node "as-is".

  2. A template overrides the identity rule for an OBR element that is its parent's second OBR child. Here we generate the wrapper element SENSITIVITY and process all following nodes in a special mode, named "inGroup".

  3. The template that matches any element in "ingroup" mode simply calls the identity rule. Alternatively, here we could simply use an <xsl:copy-of select="."/> instruction.

  4. To suppress the identity template's copying to the output (in normal, anonymous mode) the elements that follow the second OBR, we specify another template rule that matches any such element and has an empty body, which effectively prevents any such element from being copied to the output. This template overrides and suppresses the identity rule.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜