2016-09-14 1 views
0

Я не уверен, что это даже возможно с xslt, но здесь. Мне нужно разбить xml из статей на разные части.xslt: Как обернуть различные теги новыми тегами

Мне нужно, чтобы получить все XML, пока первый DIV с именем класса полной ширины и завернуть, что в DIV с именем класса узкой пленкой.
полная ширина div необходимо обернуть с помощью div с именем класса широкоформатный.

Затем начинается новый div с закрытием класса и всем xml до тех пор, пока следующий div с классом полной ширины не перейдет в это. И так далее.

Это упрощенная версия xml. Теги могут иметь вложенный контент, а также атрибуты.

<p>lorem</p> 
<div>ipsum</div> 
<div class="full-width"> 
    <img src="image.jpg" /> 
</div> 
<p>lorem</p> 
<p>ipsum</p> 
<div class="full-width"> 
    <img src="image.jpg" /> 
</div> 
<div class="narrow-width"> 
    <img src="image.jpg" /> 
</div> 
<p>lorem</p> 
<div class="full-width"> 
    <img src="image.jpg" /> 
</div> 
<div class="full-width"> 
    <img src="image.jpg" /> 
</div> 
<table>ipsum</table> 
<p>lorem</p> 
<p>ipsum</p>   
<div class="narrow-width"> 
    <img src="image.jpg" /> 
</div> 

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

<div class="narrow-wrap"> 
    <p>lorem</p> 
    <div>ipsum</div> 
</div> 

<div class="wide-wrap"> 
    <div class="full-width"> 
     <img src="image.jpg" /> 
    </div> 
</div> 

<div class="narrow-wrap"> 
    <p>lorem</p> 
    <p>ipsum</p> 
</div> 

<div class="wide-wrap"> 
    <div class="full-width"> 
     <img src="image.jpg" /> 
    </div> 
</div> 

<div class="wide-wrap"> 
    <div class="narrow-width"> 
     <img src="image.jpg" /> 
    </div> 
</div> 

<div class="narrow-wrap"> 
    <p>lorem</p> 
</div> 

<div class="wide-wrap"> 
    <div class="full-width"> 
     <img src="image.jpg" /> 
    </div> 
</div> 

<div class="wide-wrap"> 
    <div class="full-width"> 
     <img src="image.jpg" /> 
    </div> 
</div> 

<div class="narrow-wrap"> 
    <table>ipsum</table> 
    <p>lorem</p> 
    <p>ipsum</p>   
    <div class="narrow-width"> 
     <img src="image.jpg" /> 
    </div> 
</div> 

XSL для полной ширины части будет что-то вроде этого:

<xsl:template match="div[contains(concat(' ', @class, ' '), ' full-width ')]"> 
    <div> 
     <xsl:attribute name="class"> 
      wide-wrap 
     </xsl:attribute> 
     <xsl:copy-of select="."></xsl:copy-of> 
    </div> 
</xsl:template> 

Часть обертывание всего остального содержимого в блоках divs узким обтеканием класса за пределами меня. Возможно ли это, и если да, то как?

+0

'fraid Я должен сфокусироваться, потому что этот вопрос не показывает никаких исследований. что ты уже испробовал? Насколько вы знаете о XSLT? Есть ли причина, по которой вам нужно использовать XSLT вместо других потенциально более способных методов преобразования XML? – Cauterite

+0

@Cauterite: Downvote из-за отсутствия усилий, показанных в вопросе, если вы должны, но критиковать OP при выборе XSLT не подходит: (1) это вызов OP, а не ваш, и (2) вы ошибаетесь: нет более способных Метод преобразования XML. – kjhughes

+0

Я не имел в виду, что XSLT обязательно является плохим выбором. – Cauterite

ответ

1

См group-adjacent пример https://www.w3.org/TR/xslt20/#grouping-examples и попробовать <xsl:for-each-group select="*" group-adjacent="not (@class = 'full-width')">, то, как в примере, проверьте ключ и заверните current-group() соответственно каждый элемент в группе.

С помощью этого подхода вы получите

<?xml version="1.0" encoding="UTF-8" ?> 
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 
    <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" /> 

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

    <xsl:template match="body"> 
     <xsl:copy> 
      <xsl:for-each-group select="*" group-adjacent="not (@class = 'full-width')"> 
       <xsl:choose> 
        <xsl:when test="current-grouping-key()"> 
         <div class="narrow-wrap"> 
          <xsl:apply-templates select="current-group()"/> 
         </div> 
        </xsl:when> 
        <xsl:otherwise> 
         <xsl:apply-templates select="current-group()"/> 
        </xsl:otherwise> 
       </xsl:choose> 
      </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="div[contains(concat(' ', @class, ' '), ' full-width ')]"> 
     <div class="wide-wrap"> 
      <xsl:copy-of select="."></xsl:copy-of> 
     </div> 
    </xsl:template> 
</xsl:transform> 

онлайн на http://xsltransform.net/6rewNxQ.

+0

Большое спасибо. Я ценю, что вы ссылаетесь на документацию, а также на онлайн-пример. Отличный ответ. – Shaidar