2015-03-18 2 views
0

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

Если у меня есть следующий XSL файл:

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

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

<xsl:template match="input"> 
    <output> 
     <xsl:call-template name="flattenText"> 
      <xsl:with-param name="node" select="current()"></xsl:with-param> 
     </xsl:call-template> 
    </output> 
</xsl:template> 

<xsl:template name="flattenText"> 
    <xsl:param name="node"/> 
    <xsl:for-each select="$node/node()"> 
     <xsl:if test="self::text()"> 
      <xsl:value-of select="string(.)"/> 
     </xsl:if> 
     <xsl:if test="self::*"> 
      <xsl:call-template name="flattenText"> 
       <xsl:with-param name="node" select="."/> 
      </xsl:call-template> 
     </xsl:if> 
    </xsl:for-each> 
</xsl:template> 

И запустить его на этом входе:

<?xml version="1.0" encoding="UTF-8"?> 
<root> 
<input>This <span class="blah">text</span> should be flattened.</input> 
</root> 

я получаю этот выход, который я ожидал:

<?xml version="1.0" encoding="UTF-8"?> 
<output>This text should be flattened.</output> 

Но если я добавлю в этом шаблоне в нижней части файла XSL:

<xsl:template match="span[@class = 'yuk']"> 
    <span> 
     <xsl:attribute name="class">poo</xsl:attribute> 
     <xsl:apply-templates /> 
    </span> 
</xsl:template> 

я получаю это:

<?xml version="1.0" encoding="UTF-8"?> 
<output>This should be flattened.</output> 

Содержание размаху уйти, даже если 1) Я не применяя этот шаблон в любом месте, Я вижу, и 2) он не должен даже соответствовать диапазону ввода, потому что он имеет класс «бла», и шаблон должен соответствовать классу «yuk».

Может ли кто-нибудь сказать мне, что происходит, и как я могу это исправить? Должно быть, я просто ошибаюсь.

Я использую трансформатор JAXP (com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl) в Oxygen XML Editor 16.1, но у меня такая же проблема в Eclipse. Saxon 6.5.5 работает, но я не могу использовать это для своего проекта.

Любая помощь очень ценится!

UPDATE:

Я ценю помощь и попытки воспроизвести мою проблему каждого. Мой коллега смог воспроизвести его, поэтому я все еще думаю, что что-то действительно не так. В случае, если кто заинтересован, вот некоторая информация о моей ситуации:

  • Windows 7 Enterprise Edition, 64-разрядная, Service Pack 1
  • Java -версия: Java версии "1.8.0_31" Java (TM) SE Runtime Environment (сборка 1.8.0_31-b13) Java HotSpot (TM) 64-разрядный сервер VM (сборка 25.31-b07, смешанный режим)
  • Я получаю это предупреждение при запуске JAXP преобразований в кислороде: " [JAXP ] ВНИМАНИЕ: 'org.apache.xerces.jaxp.SAXParserImpl: Свойство' http://javax.xml.XMLConstants/property/accessExternalDTD 'не распознано.' 'Я не знаю, важно это или нет.

Я работаю над старой базой кода, которая настроена для использования трансформатора JAXP. Есть трудная и жесткая временная шкала, чтобы выполнить эту работу, и я думаю, что переход на Саксон прямо сейчас повлечет за собой слишком большие изменения и риск.

+0

Я не могу воспроизвести вашу проблему. Добавление указанного шаблона ** не ** изменяет результат. Протестировано с помощью [Xalan 2.7.1] (http://xsltransform.net/bdxtqg/1), libxslt и Saxon. - P.S. Я считаю, что ваша таблица стилей излишне сложна, но это не имеет никакого отношения к вашему вопросу. –

+0

Также не может воспроизвести: oXygen 15.2 с различными XSLT-процессорами; SaxonHE9-5-1-2J напрямую. Подозрительная ошибка пользователя. Проверьте консоль/журналы ошибок и убедитесь, что вы не смотрите на устаревший вывод. – kjhughes

+0

Почему вы можете использовать JAXP только для своего проекта? –

ответ

0

Как уже отмечалось несколькими людьми, результат, который вы получаете, не имеет смысла, но ваш шаблон flattenText довольно не нужен. Вы можете заменить это:

<xsl:call-template name="flattenText"> 
    <xsl:with-param name="node" select="current()"></xsl:with-param> 
</xsl:call-template> 

с этим:

<!-- Will work the same as flattenText current node is an element --> 
<xsl:value-of select="." /> 

и удалить flattenText шаблон. Возможно, это устранит вашу проблему.

+0

Большое спасибо. Это был самый полезный ответ. Моя фактическая ситуация с кодом была немного сложнее, но я смог включить ваше предложение, и это, похоже, обошло проблему. Я не понял, что значение-будет получать текст вложенных элементов. –

+0

@tookie_styles Да, так определяется значение [string value] (http://www.w3.org/TR/xpath/#element-nodes) элемента, а 'value-of' выводит строковое значение независимо от того, что он выбирает: _ «Строковое значение узла элемента - это конкатенация строковых значений всех потомков текстовых узлов узла элемента в порядке документа». _ – JLRishe

0

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

Смежные вопросы