Как применить преобразование XSLT, включающее пробелы, в документ XML с использованием tDOM? - PullRequest
1 голос
/ 27 октября 2011

У меня есть какой-то XML вида:

<definitions devices="myDevice">
    <reg offset="0x0000" mnem="someRegister">
        <field mnem="someField" msb="31" lsb="24 />
        ...
    </reg>
    ...
</definitions>

Я хочу, чтобы XML был полной ссылкой, и использую XSLT для преобразования его в HTML для документации, .h для сборки (и, возможно, других форм).

HTML-версия работает нормально и создает таблицу для каждого регистра со строкой для каждого поля:

... (header boilerplate removed)
<xsl:for-each select="definitions/reg">
  <table>
    <tr>
      <th><xsl:value-of select="@offset"/></th>
      <th><xsl:value-of select="@mnem"/></th>
    </tr>
    <xsl:for-each select="field">
        <tr>
            <td><xsl:value-of select="@msb"/>..<xsl:value-of select="@lsb"/></td>
            <td><xsl:value-of select="@mnem"/></td>
        </tr>
    </xsl:for-each>
  </table>
</xsl:for-each>

Преобразование в .h не очень хорошо. Я полностью не могу сгенерировать необходимые пробелы в выводе:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="definitions/reg">
#define <xsl:value-of select="translate(@mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    <xsl:text> </xsl:text>
    <xsl:value-of select="@offset"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>

Я надеюсь, что для получения результата:

#define SOMEREGISTER 0x0000

Но я на самом деле получаю:

#define SOMEREGISTER0x0000

Я не понимаю, почему я получаю пробел после «#define», но не после пробужденной мнемоники. Я пробовал более простое решение с использованием только встроенного пространства с теми же результатами.

Я слишком новичок в этом (XSLT), чтобы знать, что я а) делаю это неправильно или б) нашел ограничение в tDOM .

Ответы [ 3 ]

2 голосов
/ 27 октября 2011

Тестирование с этим:

# I could have read these from a file I suppose...
set in {<definitions devices="myDevice">
<reg offset="0x0000" mnem="someRegister">
<field mnem="someField" msb="31" lsb="24" />
</reg>
</definitions>}
set ss {<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="definitions/reg">
<xsl:text>#define </xsl:text>
<xsl:value-of select="translate(@mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
<xsl:text xml:space="preserve"> </xsl:text>
<xsl:value-of select="@offset"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>}

# Interesting code starts here
package require tdom
set indoc [dom parse $in]
set xslt [dom parse -keepEmpties $ss]
set outdoc [$indoc xslt $xslt]
puts [$outdoc asText]

Я считаю, что это работает. Проблема в том, что анализатор tDOM неправильно обрабатывает атрибут xml:space; без волшебной опции -keepEmpties, all пустые строки удаляются из таблицы стилей, что приводит к неправильной таблице стилей XSLT. Но с опцией, кажется, делает правильную вещь.

Обратите внимание, что сам движок XSLT работает правильно. Это синтаксический анализатор XML / построитель DOM. (Я думаю, что это ошибка; я посмотрю, где сообщить об этом.)

0 голосов
/ 27 октября 2011

У вас не указан метод вывода во второй таблице стилей, поэтому по умолчанию будет XML.Я бы посоветовал вам использовать метод вывода «текст», а затем использовать <xsl:text> элементы для любого литерального вывода.Проверьте этот пример:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" />
    <xsl:template match="/">
        <xsl:for-each select="definitions/reg"><xsl:text>#define </xsl:text><xsl:value-of select="translate(@mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/><xsl:text> </xsl:text><xsl:value-of select="@offset"/><xsl:text>&#10;</xsl:text>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

РЕДАКТИРОВАТЬ: кстати, что &#10; в конце - это код символа.Это просто десятичное значение кода ASCII для перевода строки.Это гарантирует, что вы начинаете новую строку для следующей записи reg.Если вам нужно соглашение Windows / DOS (возврат каретки + перевод строки), используйте &#13;&#10;.

0 голосов
/ 27 октября 2011

За: http://www.ibm.com/developerworks/xml/library/x-tipwhitesp/index.html

Попробуйте использовать директиву сохранения места:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="definitions/reg">
    <xsl:text xml:space="preserve">#define </xsl:text>
    <xsl:value-of select="translate(@mnem,'abcdefghijklmnopqrstuvwxyz','ABCDEFGHIJKLMNOPQRSTUVWXYZ')"/>
    <xsl:text xml:space="preserve"> </xsl:text>
    <xsl:value-of select="@offset"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...