Таблица стилей xslt - xml в csv: ошибка при использовании for-each l oop over dynamici c results-document (exist-db) - PullRequest
1 голос
/ 26 января 2020

xslt newb ie и здесь. Я предвосхищу это, сказав, что - как и многие здесь задающие вопросы - я пришел из другого фона программирования, поэтому я не до конца понимаю циклы в xslt, и я, вероятно, придумал искаженный метод, чтобы попробовать чтобы делать то, что я хочу сделать здесь, и я на 100% открыт для изучения других, лучших методов, если все это ужасно ошибочно.

Что я хочу сделать: перебирать коллекцию xml файлы и выходные файлы csv. Я знаю, как go один за другим и делать это, но я хочу автоматизировать это для целой партии файлов. Я попытался выяснить работу с коллекциями в xslt и сдался после многих неудачных попыток.

Каждый файл tei / xml назван с уникальным трехсимвольным кодом: esmpeople. xml, tdspeople . xml, ldbpeople. xml

У меня есть еще один файл tei / xml, в котором перечислены эти коды: коды. xml

Итак, мои мысли было то, что я oop над кодами. xml, захватить каждый код, затем найти соответствующий файл xml и вывести файл CSV. Вот мой код:

коды. xml

<?xml version="1.0"?>
<?xml-model href="http://www.tei-c.org/release/xml/tei/custom/schema/relaxng/tei_all.rng" type="application/xml"
    schematypens="http://purl.oclc.org/dsdl/schematron"?><?xml-stylesheet type="text/xsl" href="../xslt/csv-transform-people.xsl"?>
    <TEI xmlns="http://www.tei-c.org/ns/1.0">
    <teiHeader>
        <fileDesc>
            <titleStmt>
                <title/>
            </titleStmt>
            <publicationStmt>
                <p/>
            </publicationStmt>
            <sourceDesc>
<listBibl>
<bibl>
        <note name="workref">OBRAESM</field>
        <note name="workname">Escenas matritenses</field>
        <note name="workauthor">Mesonero Romanos</field>
    </bibl>
    <bibl>
        <note name="workref">OBRATDS</field>
        <note name="workname">Tiempo de silencio</field>
        <note name="workauthor">Luis Martín-Santos</field>
    </bibl>

    <bibl>
        <note name="workref">OBRALDB</field>
        <note name="workname">Luces de Bohemia</field>
        <note name="workauthor">Ramón del Valle-Inclán</field>
    </bibl>
</listBibl>
    </sourceDesc>
        </fileDesc>
        <profileDesc><p/></profileDesc>
    </teiHeader>
    <text>
        <body>
            <p/>
        </body>
    </text>
</TEI>

esmpeople. xml

 <listPerson>
        <person xml:id="PERSSANISIDRO"/>
        <person xml:id="PERSHORACIO"/>
        <person xml:id="PERSBARTOLOMEARGENSOLA"/>
</listPerson>

tdspeople. xml

<listPerson>
        <person xml:id="PERSPEDRO"/>
        <person xml:id="PERSAMADOR"/>
        <person xml:id="PERSRAMONYCAJAL"/>
<listPerson>

ldbpeople. xml

 <listPerson>
        <person xml:id="PERSMAXESTRELLA"/>
        <person xml:id="PERSMADAMACOLLET"/>
        <person xml:id="PERSBUEYAPIS"/>
<listPerson>

csv-transform-people.xsl

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:csv="csv:csv" xmlns:tei="http://www.tei-c.org/ns/1.0" version="1.0">
        <xsl:output omit-xml-declaration="yes" method="text" encoding="utf-8"/>
        <xsl:variable name="separator" select="','"/>
        <xsl:variable name="newline" select="'&#xA;'"/>


        <xsl:template match="/">

         <xsl:for-each select="//tei:listBibl/tei:bibl">

<!--THIS WAS THE PROBLEM-->
        <!--xsl:variable name="workref" select="//tei:note[@name='workref']"/-->

<!--FIX-->
<xsl:variable name="workref" select="tei:note[@name='workref']"/>

        <xsl:variable name="workreflc" select="lower-case($workref)"/>
        <xsl:variable name="workrefshort" select="replace($workref,'OBRA','')"/>
        <xsl:variable name="workrefshortlc" select="lower-case($workrefshort)"/>

        <xsl:variable name="sourcedocuri" select="concat('xmldb:exist://admin:password@00.00.00.00:8080/exist/xmlrpc/db/madrid/xml/',$workrefshortlc,'people.xml')"/>
        <xsl:variable name="sourcedoc" select="doc($sourcedocuri)"/>
        <xsl:variable name="sourcedocperson" select="$sourcedoc//tei:person"/>
            <xsl:result-document href="xmldb:exist://admin:password@00.00.00.00:8080/exist/xmlrpc/db/madrid/csv/people2-{$workreflc}.csv">

                <xsl:text>persref</xsl:text>
                <xsl:value-of select="$separator"/>
                 <xsl:text>persworks</xsl:text>
                <xsl:value-of select="$newline"/>
                <xsl:for-each select="$sourcedocperson">
                    <xsl:variable name="people">
                        <xsl:value-of select="@xml:id"/>
                    </xsl:variable>
                    <xsl:value-of select="$people"/>
                    <xsl:value-of select="$separator"/>

                   <xsl:value-of select="$workref"/>
                    <xsl:value-of select="$newline"/>
                </xsl:for-each>

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

</xsl:stylesheet>

Ожидаемый результат: три файла CSV, сохраненные в каталоге csv: people-obraesm.csv, people-obratds.csv, people-obraldb.csv

Результат, который я получаю: people-obraesm.csv создается на 100% правильно, но потом я получить эту ошибку:

Произошла ошибка: невозможно записать более одного результирующего документа в один и тот же URI

Так что я могу получить доступ ко всем файлам xml и записать файлы в Каталог / csv / без проблем с разрешениями. Учитывая ошибку, кажется, проблема с l oop в моей таблице стилей и / или общих логах c. Очень надеюсь выяснить, где я ошибся здесь, потому что в любое время мне нужно использовать циклы в xslt, я go в глубоком режиме проб и ошибок!

ОТВЕТ: Я изменил csv-transform -people.xsl выше по предложению Мартина, и теперь это работает!

1 Ответ

1 голос
/ 26 января 2020

Внутри <xsl:for-each select="//tei:listBibl/tei:bibl"> контекстным узлом является обработанный //tei:listBibl/tei:bibl, поэтому любой выбор должен быть относительно этого, то есть вместо <xsl:variable name="workref" select="//tei:note[@name='workref']"/> вы хотите, чтобы <xsl:variable name="workref" select="tei:note[@name='workref']"/>.

On примечание: при использовании XSLT 2 или 3 обычно лучше использовать адекватную версию (то есть version="2.0" или version="3.0") в вашем XSLT, а не version="1.0", поскольку это переводит процессор XSLT в обратную совместимость с XPath 1.0 Режим. Это можно сделать только в случае перемещения таблицы стилей XSLT 1.0, ранее обработанной процессором XSLT 1, на процессор XSLT 2 или 3.

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