2015-07-13 2 views
0

Я пытаюсь сделать преобразование на каком-либо XML с помощью XSLT.XSLT выбор текста, который содержит сильные теги

Мой xml есть;

<body> 
     <p> 
     <a href="http://www.zz.com/abc/z/0/z3970z88-0475-11dz-8603-00144zeabdc1.html#slide0"></a> 
     Some <strong>strong</strong> text 
     </p> 
    </body> 

и я хочу преобразовать его;

<body> 
     <slideshow data-uuid="z3970z88-0475-11dz-8603-00144zeabdc1/> 
     <p>Some <strong>strong</strong> text</p> 
    </body> 

Что я до сих пор;

<xsl:template match="/body/p[a[substring(@href, string-length(@href) - 6) = '#slide0' and string-length(text()) = 0] and count(*) = 1]"> 
     <xsl:apply-templates select="a" /> 
     <xsl:if test="string-length(text()) > 0"> 
     <p> 
      <xsl:value-of select="text()"/> 
     </p> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="a[substring(@href, string-length(@href) - 6) = '#slide0' and string-length(text()) = 0]"> 
     <slideshow> 
     <xsl:attribute name="data-uuid"> 
      <xsl:value-of select="substring-before(substring(@href, string-length(@href) - 47), '.html#slide0')" /> 
     </xsl:attribute> 
    </xsl:template> 

Но это работает только, если текст не имеет детей, такие как <strong> тег или другой тег <a>.

У кого-нибудь есть решение, которое подберет все это.

ответ

0

Я придумал этот XSLT. Я не уверен, что если если будет соответствовать каждой цели вы можете придумать, но это не решает пример вы дали здесь:

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:template match="/body/p[a]"> 
     <xsl:apply-templates select="a" /> 
     <p> 
      <xsl:copy-of select="./node()[not(self::a)]" /> 
     </p> 
    </xsl:template> 

    <xsl:template match="a[substring(@href, string-length(@href) - 6) = '#slide0' and string-length(text()) = 0]"> 
     <slideshow> 
      <xsl:attribute name="data-uuid"> 
       <xsl:value-of select="substring-before(substring(@href, string-length(@href) - 47), '.html#slide0')" /> 
      </xsl:attribute> 
     </slideshow> 
    </xsl:template> 
</xsl:stylesheet> 

Идея заключается в том, чтобы скопировать содержимое тега <p> рассчитывать на <a> тег. Я изменил условие на первые шаблоны Apply, но вам не нужно это делать. Это просто сделало меня более удобочитаемым.

+0

Спасибо за ваш ответ. Однако, похоже, это не делает трюк. Ответ я получаю '

<слайд-шоу данных UUID =«z3970z88-0475-11dz-8603-00144zeabdc1»/> Некоторые сильный текст

' Когда я пытаюсь это только с текстом и без сильного тега это работает (но он работал для этого сценария в моем предыдущем решении). –

+0

Вы все еще используете свое первоначальное состояние? Поскольку счетчик (*) не позволит вам совместить тэг p. Зачем нужен этот счет? – cvesters

+0

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

0

В тех случаях, когда вы преобразующих только часть вашего XML, как правило, это хороший подход, чтобы начать с Identity Template

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

Это означает, что, вместо того, чтобы использовать xsl:value-of в шаблоне, используйте xsl:apply-templates и пусть идентичность Templ

<xsl:if test="string-length(text()) > 0"> 
     <p> 
      <xsl:apply-templates select="@*|node()[not(self::a)]"/> 
     </p> 
    </xsl:if> 

Попробуйте XSLT

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml" encoding="UTF-8" indent="yes" /> 

    <xsl:template match="p[a[substring(@href, string-length(@href) - 6) = '#slide0' and string-length(text()) = 0] and count(*) = 1]"> 
     <xsl:apply-templates select="a" mode="slideshow" /> 
     <xsl:if test="string-length(text()) > 0"> 
      <p> 
       <xsl:apply-templates select="@*|node()[not(self::a)]"/> 
      </p> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="a" mode="slideshow"> 
     <slideshow> 
     <xsl:attribute name="data-uuid"> 
      <xsl:value-of select="substring-before(substring(@href, string-length(@href) - 47), '.html#slide0')" /> 
     </xsl:attribute> 
     </slideshow> 
    </xsl:template> 

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

Обратите внимание на использование «режима» в шаблоне, соответствующем a. Это было сделано исключительно для того, чтобы избежать двукратного кодирования состояния с длинной ветвью.

Как и в сторону, вы используете Attribute Value Templates в a шаблоне, чтобы упростить его

<xsl:template match="a" mode="slideshow"> 
     <slideshow data-uuid="{substring-before(substring(@href, string-length(@href) - 47), '.html#slide0')}" /> 
</xsl:template> 
Смежные вопросы