Merging html files using XSLT?

吃可爱长大的小学妹 提交于 2020-01-03 06:37:27

问题


I am transforming multiple html files to one file mean multiple chapters in a book. For that i am recieving text file where is the sequence of file list. While transforming i am not getting the proper sequences of the chapters:

TXT FILE:

FilePath=d:\Amrendra\edgar xml-html\All\Edger_Final\xml\07_Document_Edgar17Nov.out.indd,d:\Amrendra\edgar xml-html\All\Edger_Final\xml\02_Document_Edgar17Nov.out.indd,d:\Amrendra\edgar xml-html\All\Edger_Final\xml\03_Document_Edgar17Nov.out.indd,d:\Amrendra\edgar xml-html\All\Edger_Final\xml\04_Document_Edgar17Nov.out.indd,d:\Amrendra\edgar xml-html\All\Edger_Final\xml\05_Document_Edgar17Nov.out.indd,d:\Amrendra\edgar xml-html\All\Edger_Final\xml\06_Document_Edgar17Nov.out.indd,d:\Amrendra\edgar xml-html\All\Edger_Final\xml\01_FrontMatter_Edgar17Nov.out.indd

XSLT for merging:

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

    <xsl:character-map name="m1">
        <xsl:output-character character="•" string="&amp;bull;"/>
        <xsl:output-character character="&#160;" string="&amp;nbsp;"/>
        <xsl:output-character character="’" string="&amp;rsquo;"/>

    </xsl:character-map>

    <xsl:output method="xhtml" use-character-maps="m1"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:variable name="filelist">
        <xsl:analyze-string select="unparsed-text('../book_bulidIndesign.txt')" regex="FilePath=(.*)">
            <xsl:matching-substring>
                <xsl:value-of select="normalize-space(regex-group(1))"/>
            </xsl:matching-substring>
        </xsl:analyze-string>
    </xsl:variable>

    <xsl:variable name="file-seq">
        <map>
        <xsl:for-each select="tokenize($filelist, ',')">
            <file>
                <xsl:attribute name="pos" select="position()"/>
                <xsl:value-of select="iri-to-uri(concat('file:///', replace(replace(replace(., '\\InDesign\\', '\\XML\\'), 'indd$', 'html'), '\\', '/')))"/>
            </file>
        </xsl:for-each>
        </map>
    </xsl:variable>


    <xsl:template match="/">
        <html>
            <body style="font: 10pt Times New Roman, Times, Serif">
                <xsl:for-each select="document($file-seq/map/file)">
                    <xsl:apply-templates select="/node()/body/node()"/>
                </xsl:for-each>
            </body>
        </html>
    </xsl:template>

</xsl:stylesheet>

NOTE : If i am try to print the mapping of chapters its working well! All html files are available on the specific path.


回答1:


To sort the output by the text contents in the files simply add the following line after your for-each in your template:

<xsl:sort select="/node()/body/node()/text()" />



回答2:


Thanks Every one for the suggestions i did this in storing the documents inside the variable as per the order and after apply these way link:

<xsl:variable name="filelist">
        <xsl:analyze-string select="unparsed-text('../book_bulidIndesign.txt')" regex="FilePath=(.*)">
            <xsl:matching-substring>
                <xsl:value-of select="normalize-space(regex-group(1))"/>
            </xsl:matching-substring>
        </xsl:analyze-string>
    </xsl:variable>

    <xsl:variable name="all-chapter">
        <xsl:for-each select="tokenize($filelist, ',')">
            <xsl:variable name="c_path">
                <xsl:value-of select="concat('file:///', iri-to-uri(replace(replace(replace(., '\\InDesign\\', '\\XML\\'), 'indd$', 'html'), '\\', '/')))"/>
            </xsl:variable>
            <xsl:copy-of select="document($c_path)"/>
        </xsl:for-each>
    </xsl:variable>

    <xsl:template match="/">
        <html>
            <body style="font: 10pt Times New Roman, Times, Serif">
                <xsl:apply-templates select="$all-chapter/node()/body/node()"/>
                <!--<xsl:apply-templates select="$all-chapter/node()"/>-->
            </body>
        </html>
    </xsl:template>



回答3:


In this construct:

<xsl:for-each select="document($file-seq/map/file)">
    <xsl:apply-templates select="/node()/body/node()"/>
</xsl:for-each>

The specification states: "The sequence of nodes returned by the [document] function is in document order, with no duplicates. This order has no necessary relationship to the order in which URIs were supplied in the ... argument."

If you want a specific order (with duplicates retained), you can achieve this using

<xsl:for-each select="$file-seq/map/file ! document(.)">
    <xsl:apply-templates select="/node()/body/node()"/>
</xsl:for-each>

The "!" operator is XPath 3.0, in 2.0 you can instead do:

<xsl:for-each select="$file-seq/map/file">
    <xsl:apply-templates select="document(.)/node()/body/node()"/>
</xsl:for-each>

Actually I'm not 100% convinced this will solve your problem. There may be other factors affecting the result order that I have overlooked. But this is certainly ONE area where you have made unwarranted assumptions about the order of results.



来源:https://stackoverflow.com/questions/48397222/merging-html-files-using-xslt

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!