Почему элемент <area>заставляет XSLT отбрасывать содержимое элемента и закрывать тег? - PullRequest
1 голос
/ 22 июня 2011

Запустив XSLT-процессор под PHP 5.2.11, я столкнулся с странной ошибкой и смог скопировать ее также с демоверсией W3Schools XSLT .

Это упрощенный случай, который все еще вызывает ошибку. Моя цель - взять иерархически структурированный XML и «сплющить» его для создания структуры строк.

Введите:

<?xml version="1.0"?>
<profiles>
<Subrecipient>
    <SubrecipientName>TESTING123</SubrecipientName>
    <Service>
        <ServiceName>BEFORE</ServiceName>
        <area>BETWEEN</area>
        <TypeDesc>AFTER</TypeDesc>
    </Service>
</Subrecipient>
</profiles>

стилевой:

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html"/>
<!--generally, don't output nodes that have no children -->
<xsl:template match="//*[not(*)]" />
<!-- except in "dataout" mode, namely when we're matching at a low level -->
<xsl:template match="//*[not(*)]" mode="dataout" >
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="Service">
<row>
<!--next line selects all childless children of ancestors -->
<xsl:apply-templates select="ancestor::*/child::*[not(*)]" mode="dataout" />
<xsl:apply-templates  select="*[not(*)]" mode="dataout"  /> 
</row>
</xsl:template>
</xsl:stylesheet>

Желаемый результат (интервал для ясности):

<row><subrecipientname>TESTING123</subrecipientname>
     <servicename>BEFORE</servicename>    
     <area>BETWEEN</area>
     <typedesc>AFTER</typedesc>
</row>    

Фактический результат (например, из демонстрационной программы W3Schools XSLT, указанной выше):

<row><subrecipientname>TESTING123</subrecipientname>
      <servicename>BEFORE</servicename>
      <area>
      <typedesc>AFTER</typedesc>
</row>

т.е. процессы XSLT генерируют неверный xml, пропуская как содержимое, так и закрывающий тег для элемента "area". Если я переименую этот элемент в «area_», все будет хорошо.

Я не знаю, какой процессор XSLT использует W3Schools, так что, возможно, это просто ошибка процессора PHP XSLT, или есть что-то глубокое (и замечательное?) В XSLT и XPATH, я не понимаю.

У меня есть обходной путь, но я бы предпочел понять, с чем я столкнулся здесь. Спасибо за любую помощь.

Ответы [ 2 ]

2 голосов
/ 22 июня 2011

Да, это правильно; Основная причина этого заключается в том, что вы используете xsl:output с методом html. При этом процессор может выводить не правильно сформированные документы. Тег area - это тег HTML без конечного тега, как и многие другие, например br и т. Д. Вы можете решить свою проблему, просто изменив метод вывода на XML.

<xsl:output method="xml"/>

Вы можете испытать то же поведение с любым процессором, совместимым с XSLT 1.0 (например, Saxon 6.5).

0 голосов
/ 22 июня 2011

Вот вывод, который я получаю в демоверсии w3schools:

<row>
    <subrecipientname>TESTING123</subrecipientname>
    <servicename>BEFORE</servicename>
    <area>BETWEEN</area>
    <typedesc>AFTER</typedesc>
</row>

Следует отметить, что область является элементом html, и из-за этого могут возникнуть проблемы.

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