XSL Transform - Filepath с пробелами - PullRequest
0 голосов
/ 09 апреля 2020

Я пытаюсь выполнить XSL-преобразование для преобразования файла CSV в XML, используя Java и Saxon.

<xsl:when test="unparsed-text-available($pathToCSV)">

Я вызываю команду следующим образом: C: \ Program Файлы (x86) \ Java \ jdk1.8.0_191 \ bin> java .exe -jar c: \ saxon \ saxon9he.jar -o: "E: \ Temp \ Папка имеет пробелы \ test. xml" -it: main -xsl: E: \ Temp \ csvxml_TEST.xsl pathToCSV = "E: \ Temp \ Папка имеет пробелы \ test.csv"

Сценарий работает нормально, если в пути ввода нет пробелов. Есть ли способ заставить этот скрипт работать, когда в пути ввода есть пробелы?

Полный код XSL:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:fn="fn"
    exclude-result-prefixes="xs fn">

<xsl:output indent="yes" encoding="UTF-8"/>

<xsl:param name="pathToCSV" />

<xsl:function name="fn:getTokens" as="xs:string+">
    <xsl:param name="str" as="xs:string"/>
        <xsl:analyze-string select="concat($str, ',')" regex='(("[^"]*")+|[^,]*),'>
            <xsl:matching-substring>
                <xsl:sequence select='replace(regex-group(1), "^""|""$|("")""", "$1")'/>
            </xsl:matching-substring>
        </xsl:analyze-string>
</xsl:function>

<xsl:template match="/" name="main">
    <xsl:choose>
        <xsl:when test="unparsed-text-available($pathToCSV)">
            <xsl:variable name="csv" select="unparsed-text(pathToCSV)"/>
            <xsl:variable name="lines" select="tokenize($csv, '&#xa;')" as="xs:string+"/>
            <xsl:variable name="elemNames" select="fn:getTokens($lines[1])" as="xs:string+"/>
            <root>
                <xsl:for-each select="$lines[position() > 1]">
                    <row>
                        <xsl:variable name="lineItems" select="fn:getTokens(.)" as="xs:string+"/>
                        <xsl:for-each select="$elemNames">
                            <xsl:variable name="pos" select="position()"/>
                            <elem name="{.}">
                                <xsl:value-of select="normalize-space($lineItems[$pos])"/>
                            </elem>
                        </xsl:for-each>
                    </row>
                </xsl:for-each>
            </root>
        </xsl:when>
        <xsl:otherwise>
            <xsl:text>Cannot locate : </xsl:text><xsl:value-of select="$pathToCSV"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
</xsl:stylesheet>

1 Ответ

0 голосов
/ 09 апреля 2020

Большинство функций XPath и XSLT работают с URI, а не с системными / os-зависимыми путями к файлам, поэтому вы можете попытаться преобразовать ваш Windows путь к файлу в URI, например,

unparsed-text(concat('file:///', replace(replace($pathToCSV, '\\', '/'), ' ', '%20')))

или

unparsed-text(iri-to-uri(concat('file:///', replace($pathToCSV, '\\', '/'))))

Обратите внимание, что файловый модуль EXPath, поддерживаемый в Saxon PE и EE (http://saxonica.com/html/documentation9.9/functions/expath-file/path-to-uri.html), имеет метод file:path-to-uri: http://expath.org/spec/file#fn .path-to-uri .

...