2010-04-21 3 views
3

У меня есть пара пользовательских самозакрывающихся тегов s1 и s2, определенных в пространстве имен x в моем xhtml. Для каждой пары тегов s1, s2, имеющих одинаковый идентификатор, я хочу добавить теги span ко всем текстовым узлам между ними. Каждая пара тегов s1, s2 имеет уникальный идентификатор. Я ищу решение на основе XSL для того же самого. Я использую Saxon java-процессор для XSL.Добавление <span> тегов ко всем текстовым узлам между пользовательскими самозакрывающимися тегами

Пример ввода:

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>This is my title</title> 
</head> 
<body> 
<h1 align="center"> 
    This is my heading 
</h1> 
<p> 
    Sample content Some text here. Some content here. 
</p> 
<p> 
    Here you go. 
</p> 
</body> 
</html> 

Пример вывода:

<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<title>This is my title</title> 
</head> 
<body> 
<h1 align="center"> 
    This <span class="spanClass" id="1">is my</span>heading 
</h1> 
<p> 
    Sample content <span class="spanClass" id="2">Some text here. Some content here.</span> 
</p> 
<p> 
    <span class="spanClass" id="3">Here you</span>go. 
</p> 
</body> 
</html> 
+0

Пожалуйста переформатировать свой код, это трудно читать. – topskip

+0

На самом деле все еще невозможно прочитать код. Пожалуйста, отформатируйте его как блок кода, а это означает, что все отступы в четырех пробелах (см. Справку по форматированию). См. Например http://stackoverflow.com/questions/2685250/xsl-numeric-generate-id – topskip

+0

Выполнено. Он отформатирован. – Rachel

ответ

2

EDIT: Модифицированная ответ на работу с образцом XHTML вы добавили.

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:x="http://www.w3.org/1999/xhtml" 
    xmlns="http://www.w3.org/1999/xhtml" 
    exclude-result-prefixes="x" 
> 
    <xsl:output method="xml" omit-xml-declaration="yes" encoding="utf-8" /> 

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

    <xsl:template match="text()[normalize-space()]"> 
    <xsl:choose> 
     <xsl:when test="preceding::x:s1[1][ 
     not(following::x:s2[1][ 
      following::text()[generate-id() = generate-id(current())] 
     ]) 
     ]"> 
     <span class="spanClass" id="{generate-id()}"> 
      <xsl:copy-of select="." /> 
     </span> 
     </xsl:when> 
     <xsl:otherwise> 
     <xsl:copy-of select="." /> 
     </xsl:otherwise> 
    </xsl:choose> 
    </xsl:template> 

    <xsl:template match="x:s1|x:s2" /> 

</xsl:stylesheet> 

Результат (разрывы строк/отступы для удобства чтения):

<html xmlns="http://www.w3.org/1999/xhtml"> 
    <head> 
    <title>This is my title</title> 
    </head> 
    <body> 
    <h1 align="center"> 
     This <span class="spanClass" id="IDATA2Q">is my</span>heading 
    </h1> 
    <p> 
     Sample content <span class="spanClass" id="IDA2A2Q">Some text here. Some content here.</span> 
    </p> 
    <p> 
     <span class="spanClass" id="IDA5A2Q">Here you</span>go. 
    </p> 
    </body> 
</html> 
+0

@Rachel: И именно поэтому вы должны * не * «составлять» XML, а использовать реальный пример. Легко пропустить существенные детали, когда составляешь материал для «упрощения» вопроса, что приводит к двойной работе для всех. Какая трата, не так ли? – Tomalak

+0

Ваше решение неплохое. +1 от меня :) –

+0

@Rachel: Просто измените свой пример XML, чтобы отразить реальность. – Tomalak

4

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

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes"/> 

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

<xsl:template match="text()[(preceding::s1 | preceding::s2)[last()][self::s1]]"> 
    <span class="spanClass" id="{generate-id()}"> 
    <xsl:copy-of select="."/> 
    </span> 
</xsl:template> 

<xsl:template match="s1|s2"/> 
</xsl:stylesheet> 

при нанесении на исходном документе XML (исправленный хорошо сформированным):

<a> 
    <b>Some <s1 id="1" />text here</b> 
    <c>Some <s2 id="1"/>more text <s1 id="2"/> here</c> 
    <d>More data</d> 
    <e>Some <s2 id="2" />more data</e> 
</a> 

производит разыскиваемого вывод:

<a> 
    <b>Some <span class="spanClass" id="IDANI2QB">text here</span></b><span class="spanClass" id="IDAOI2QB"> 
    </span><c><span class="spanClass" id="IDAQI2QB">Some </span>more text <span class="spanClass" id="IDAWI2QB"> here</span></c><span class="spanClass" id="IDAXI2QB"> 
    </span><d><span class="spanClass" id="IDAYI2QBIDAYI2QB">More data</span></d><span class="spanClass" id="IDAZI2QB"> 
    </span><e><span class="spanClass" id="IDA1I2QB">Some </span>more data</e> 
</a> 
+0

+1 Хорошо сыграл, сэр. :) – Tomalak

+0

BTW, можете ли вы объяснить, почему у одного и того же узла есть более длинный, чем обычно, id в наших результатах? – Tomalak

+0

@Rachel: Пожалуйста, обновите свой вопрос с более точным определением проблемы или задайте другой вопрос. Урок в этом состоит в том, чтобы подумать, прежде чем задавать вопрос, как лучше всего определить проблему. –