2015-10-14 9 views
0

У меня есть XML-файл, как это,XSLT - применять-шаблоны для дочернего узла и текста() узел

<content> 
    <ol> 
     <li> List<span style="color: rgb(255,0,255);">The scopeeeee of</span>this project is 
      <ol> 
       <li>nested list1</li> 
       <li>nested <span style="color: rgb(255,0,255);">The scope of this project is</span> list1</li> 
       <li>nested list1</li> 
       <li>nested list1</li> 
       <li>nested list1</li> 
      </ol> 
     </li> 
     <li> 
      <p>List<span style="color: rgb(255,0,255);">The scope of this project is to:</span></p> 
     </li> 
     <li> 
      <p>List<span style="color: rgb(255,0,255);">The scope of this project is to:</span></p> 
     </li> 
    </ol> 
</content> 

Мне нужно преобразовать над XML в следующий формат XML с помощью XSLT

ожидаемого результата,

<content> 
    <orderedList> 
     <liItem> 
      <para>List<c type="color: rgb(255,0,255);">The scopeeeee of this project is to:</c>jkhsdlkjfh</para> 
     </liItem> 
     <orderedList> 
      <liItem> 
       <para>nested list1</para> 
      </liItem> 
      <liItem> 
       <para>nested <c type="color: rgb(255,0,255);">The scope of this project is</c>list1</para> 
      </liItem> 
      <liItem> 
       <para>nested list1</para> 
      </liItem> 
      <liItem> 
       <para>nested list1</para> 
      </liItem> 
      <liItem> 
       <para>nested list1</para> 
      </liItem> 
     </orderedList> 

     <liItem> 
      <para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para> 
     </liItem> 
     <liItem> 
      <para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para> 
     </liItem> 
    </orderedList> 
</content> 

Как вы можете видеть, текстовое содержимое и узлы диапазона внутри элементов li должны покрывать <para> узел на выходе.

Я написал следующее XSL, чтобы получить этот вывод,

<xsl:template match="ol"> 
     <orderedList> 
      <xsl:apply-templates/> 
     </orderedList> 
    </xsl:template> 

    <xsl:template match="li[not(descendant::ol)]" > 
     <liItem> 
      <para> 
       <xsl:apply-templates /> 
      </para> 
     </liItem> 
    </xsl:template> 

    <xsl:template match="li[descendant::ol]" > 
     <liItem> 
      <para> 
       <xsl:apply-templates select="node()[parent::li][following-sibling::ol]"/> 
      </para> 
     </liItem> 
     <xsl:apply-templates/> 
    </xsl:template> 

    <xsl:template match="span"> 
     <c type="{@style}"> 
      <xsl:apply-templates/> 
     </c> 
    </xsl:template> 

    <xsl:template match="li/p"> 
     <xsl:apply-templates /> 
    </xsl:template> 

Единственная проблема выше XSL является наступает тогда, когда он имеет <ol><ol> внутри другой элемент. Я изо всех сил пытаюсь найти способ добавить узел <para> в текстовое содержимое, которое размещено между <li> и <ol> узлами.

выходной ток следует,

<content> 
    <orderedList> 
     <liItem> 
      <para> List<c type="color: rgb(255,0,255);">The scopeeeee of</c>this project is</para> 
     </liItem> List<c type="color: rgb(255,0,255);">The scopeeeee of</c>this project is 
     <orderedList> 
      <liItem><para>nested list1</para></liItem> 
      <liItem><para>nested <c type="color: rgb(255,0,255);">The scope of this project is</c>list1</para></liItem> 
      <liItem><para>nested list1</para></liItem> 
      <liItem><para>nested list1</para></liItem> 
      <liItem><para>nested list1</para></liItem> 
     </orderedList> 
     <liItem><para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para></liItem> 
     <liItem><para> List<c type="color: rgb(255,0,255);">The scope of this project is to:</c></para></liItem> 
    </orderedList> 
</content> 

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

ответ

4

Если ol элемент всегда придет после того, как текст в li элемент, можно просто изменить шаблон для этого

<xsl:template match="li[descendant::ol]" > 
    <liItem> 
     <para> 
      <xsl:apply-templates select="node()[following-sibling::ol]"/> 
     </para> 
    </liItem> 
    <xsl:apply-templates select="ol"/> 
</xsl:template> 

Или, может быть, это, если вы на самом деле хотели го е ol элемент внутри liItem, но только не в para

<xsl:template match="li[descendant::ol]" > 
    <liItem> 
     <para> 
      <xsl:apply-templates select="node()[following-sibling::ol]"/> 
     </para> 
     <xsl:apply-templates select="ol"/> 
    </liItem> 
</xsl:template> 

В любом случае, вы могли бы объединить два шаблона соответствие li в единый шаблон; как так:

<xsl:template match="li" > 
    <liItem> 
     <para> 
      <xsl:apply-templates select="node() except ol"/> 
     </para> 
     <xsl:apply-templates select="ol"/> 
    </liItem> 
</xsl:template> 

В качестве альтернативы, если вы хотите, чтобы справиться с несколькими ol элементов в пределах одного элемента списка, или если у вас текст после ol элемента тоже можно использовать xsl:for-each-group

<xsl:template match="li" > 
    <liItem> 
     <xsl:for-each-group select="node()" group-adjacent="boolean(self::ol)"> 
      <xsl:choose> 
       <xsl:when test="current-grouping-key() or not(normalize-space())"> 
        <xsl:apply-templates select="current-group() "/> 
       </xsl:when> 
       <xsl:otherwise> 
        <para> 
         <xsl:apply-templates select="current-group() "/> 
        </para> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:for-each-group> 
    </liItem> 
</xsl:template> 
Смежные вопросы