xsl: preserve-space нарушает остальную часть кода - PullRequest
0 голосов
/ 28 января 2020

Моя команда использует редактор XML MadCap Flare для написания технической документации с выходными документами в формате PDF и HTML. Нам нужно использовать H2s для некоторых страниц, чтобы правильно отформатировать PDF-файлы, но для целей SEO нам необходимо преобразовать их в H1s для веб-сайтов. Я написал событие сборки, которое преобразует H2s в H1s при публикации в сети sh. Однако я только что понял, что код XSL неправильно удаляет пробелы между переменными и изображениями. Я обнаружил xsl: preserve-space, но использование этого нарушает остальную часть кода, так что H2 никогда не преобразуются в H1. Мне нужно найти способ выполнить преобразование и , чтобы сохранить пространство.

Вот фрагмент кода источника HTM (и, прежде чем вы спросите, нет, Я не могу удалить теги span, они вставляются Flare при преобразовании переменных в текст):

                <div role="main" id="mc-main-content">
                    <h2><span class="GlobalCompany">BeyondTrust</span> <span class="ProductsPA">Privileged Remote Access</span> Web Rep Console Requirements</h2>
                    <p>To run the <span class="GlobalCompany">BeyondTrust</span> <span class="ProductNamesWebConsole">web rep console</span> on your system...</p>

Вот командный файл , который я использую в качестве события сборки:

@ECHO Off

set outputDir=%1
@set XSLAltova=C:\Users\%username%\AltovaXML.exe

REM Create filelist
dir %outputDir%*.htm /b /s /A-D > file_list.txt
@echo ^<filelist^>^</filelist^> > pre_filelist.xml

REM XML-ize filelist
%XSLAltova% /xslt2 convert_filelist.xsl /in pre_filelist.xml  /out pre_list.xml

REM Replace starting h2 tags with h1 tags
%XSLAltova% /xslt2 h2toh1.xsl /in pre_list.xml  /out null.xml

REM Garbage collection
DEL pre_list.xml
DEL pre_filelist.xml
DEL file_list.txt

Вот convert_filelist.xsl

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

<!-- Set output style. XML with no indentations -->
    <xsl:output indent="no" method="xml" omit-xml-declaration="yes"/>

<!-- Reads the file list text file into memory as a global variable. -->
    <xsl:variable name="fileList">file_list.txt</xsl:variable>  

<!-- Parses the file list text file to create an XML list of files that can be fed to the transformer -->
    <xsl:template match="filelist">
    <!-- Create a variable that can be parsed -->
        <xsl:variable name="filelist_raw"><xsl:value-of select="unparsed-text($fileList,'UTF-8')"/></xsl:variable>
    <!-- Create a open and close file tags for each line in the list -->
        <xsl:variable name="driveLetter"><xsl:value-of select="substring-before(unparsed-text($fileList,'UTF-8'),':')"/>:<xsl:text disable-output-escaping="yes">\\</xsl:text></xsl:variable>
        <xsl:variable name="driveLetterReplacement"><xsl:text disable-output-escaping="yes">&lt;file&gt;</xsl:text><xsl:value-of select="$driveLetter"/></xsl:variable>
    <!-- Generate an xml tree. The value-of is doing a text-level replacement. Looking for the drive letter and replacing it  -->
    <!-- with the file open tag and drive letter. Looking for the file extension and replacing with the extension and file close tag.-->
        <file_list><xsl:value-of select="replace(replace($filelist_raw,'.htm','.htm&lt;/file&gt;'),$driveLetter,$driveLetterReplacement)" disable-output-escaping="yes"/></file_list>
    </xsl:template>
</xsl:stylesheet>

А вот h2toh1.xsl :

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" 
    xmlns:MadCap="http://www.madcapsoftware.com/Schemas/MadCap.xsd" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- Set output style. -->
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>
    <xsl:preserve-space elements="node()"/>

<!-- Begin traversing the list of files in the output folder. -->
    <xsl:template match="file_list">
        <xsl:for-each select="*">
            <xsl:variable name="filename" select="."/>
            <xsl:variable name="content" select="document($filename)"/>

<!-- Generate a new output file to replace the Flare generated file. Uses the same file name. Transparent to the end user. -->
            <xsl:result-document href="{$filename}" method="html">
                <xsl:apply-templates select="document($filename)">
                    <xsl:with-param name="content" select="$content"/>
                </xsl:apply-templates>
            </xsl:result-document>

        </xsl:for-each>
    </xsl:template>

<!-- Recreate each node as it appears in the generated document -->
    <xsl:template match="*">
        <xsl:param name="content"/>
        <xsl:variable name="name" select="name(.)"/>
        <xsl:element name="{$name}">
            <xsl:for-each select="@*">
                <xsl:copy-of select="."/>
            </xsl:for-each>
            <xsl:apply-templates/>
            </xsl:element>
    </xsl:template>

<!-- Select the first header and change it to an h1. -->
    <xsl:template match="*[matches(name(), 'h\d')][1]">
        <xsl:element name="h1">
            <xsl:for-each select="@*|node()">
                <xsl:copy-of select="."/>
            </xsl:for-each>
        </xsl:element>
    </xsl:template>
</xsl:stylesheet>

Здесь вывод без xsl: preserve-space : (стиль h1, пропуски между переменными )

Вот вывод с xsl: preserve-space : ( h2 стиль, уродливый синий для контраста, с пробелами )

А вот вывод, который я хочу, но не могу иметь: ( h1 стиль, с пробелами )

В моем нынешнем виде мой сайт несколько не работает, и у меня нет готового средства исправить его, не выполнив при этом массу работы. Любая помощь будет наиболее ценной.

1 Ответ

0 голосов
/ 28 января 2020

Причина, по которой ваше объявление xsl:preserve-space нарушает код, состоит в том, что вы дали ему недопустимое значение; значение атрибута elements должно быть списком имен элементов или "*". Но это не будет полезно в любом случае; сохранение пробелов используется по умолчанию, и единственная причина для использования xsl:preserve-space состоит в том, чтобы противодействовать общему xsl:strip-space.

Вы, похоже, используете процессор XSLT Altova, который, как я подозреваю, означает, что вы используете Microsoft MS XML синтаксический анализатор, который IIR C удаляет пробелы по умолчанию при разборе XML. Если это так, то ничто из того, что вы делаете в самой таблице стилей, не повлияет на это, поскольку пробелы уже исчезли до начала обработки XSLT. Тем не менее, я не эксперт по этой комбинации продуктов, поэтому могу ошибаться.

Кстати, это, вероятно, не имеет ничего общего с вашей проблемой, но эффект установки disable-output-escaping при записи узлов в xsl:variable очень непредсказуемо. За прошедшие годы рабочая группа W3 C несколько раз меняла свое мнение относительно того, должна ли она работать (она известна как «проблема с липучкой»), и что с ней делает конкретный продукт, можно только догадываться.

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