Переписать несколько файлов и избежать ошибки. XTRE1500: Невозможно прочитать документ, который был написан во время того же преобразования - PullRequest
0 голосов
/ 31 января 2020

Пытаясь решить отдельную проблему , я переключился на процессор Saxon XSLT и изо всех сил пытался заставить синтаксис моего кода работать. Цель кода - перебрать список HTML файлов, найти первый экземпляр любого заголовка на каждой странице и преобразовать его в H1 (поскольку мы должны использовать H2 для нашего вывода PDF, но нам нужны H1 для нашего HTML output).

Я начинаю с командного файла :

set outputDir=%1
@set Saxon=C:\Users\%username%\saxon\saxon9he.jar

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

REM XML-ize filelist
java -cp %Saxon% net.sf.saxon.Transform -s:pre_filelist.xml -xsl:convert_filelist.xsl -o:pre_list.xml

REM Replace starting h2 tags with h1 tags
java -cp %Saxon% net.sf.saxon.Transform -s:pre_list.xml -xsl:h2toh1.xsl -o:null.xml

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

pause

, который находит все выходные файлы HTML и форматирует их в списке, используя 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;file:///</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(replace($filelist_raw,'.htm','.htm&lt;/file&gt;'),$driveLetter,$driveLetterReplacement),'\\','/')" disable-output-escaping="yes"/></file_list>
    </xsl:template>
</xsl:stylesheet>

И который затем преобразует первый заголовок в H1, используя 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. XML with no indentations. Normally no. -->
    <xsl:output method="xml" indent="yes" omit-xml-declaration="no"/>

<!-- 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="xml">
                <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>

Однако Затем я получаю экземпляр этих ошибок для каждого файла в списке:

Предупреждение на символе 9 в xsl: variable / @ select в строке 13 столбца 63 h2toh1.xsl: XTRE1500: Не удается прочитать документ, который был написан во время того же преобразования: file: /// C: /TechDocs/Projects/ScriptTest/Output/JPittman/Docs11/Default.htm

Предупреждение на символе 9 в xsl: apply- templates / @ выберите в строке 17 столбец 55 h2toh1.xsl: XTRE1500: не удается прочитать документ t что было написано во время того же преобразования: file: /// C: /TechDocs/Projects/ScriptTest/Output/JPittman/Docs11/Default.htm

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

1 Ответ

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

Причина, по которой ошибка определена в спецификации c, заключается в том, что порядок выполнения не определен, поэтому, если вы читаете и записываете один и тот же файл в преобразовании, то в принципе нет способа предсказать, выполнено ли чтение до записи или после. (Конечно, на практике это часто не так, потому что будет функциональная зависимость.)

Обычно вы можете обойти ограничение, на свой страх и риск, используя слегка разные URL для чтения и написать. Например, параметры запроса в конце URI (например,? Version = 1) обычно игнорируются на file:/// URI.

...