使用xsl:analyze-string并保留标记(如在标识转换中)

时间:2016-09-30 10:01:12

标签: xml xslt xslt-2.0

我想处理一个XML文件,以便在一行中两个新行之前或之后的任何内容都变成一个段落(就像在LaTeX中一样)。

这是源文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE letter SYSTEM "../Schema_and_DTD/entities.dtd">
<letter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Schema_and_DTD/letter.xsd" page_id="940"title="1695-08-17_Faeh_Georg-Bernoulli_Johann_I" catalogue_id="000055848">

<facsimile src=""/> Colendissime ac ornatissime Domine etc.

Colendissimae dominationi Vestrae gratificandi ergo, exactissima diligentia tum in Bibliotheca nostra Conventuali, tum in Bibliopolio mihi commisso perquisivi Chronicon Joannis Vitodurani<ref><i>Die Chronik Johanns von Winterthur (Chronica Iohannis Vitodurani)</i>, herausgegeben von F. Baethgen und C. Brun in: <i>Scriptores rerum Germanicarum</i>, Nova series 3, Berlin 1924.</ref>, sed nihil de eo repertum fuit.<ref>Leibniz hat die Chronik des Johannes von Winterthur später aus Bremen erhalten und in seinem <i>Codex juris gentium diplomaticus</i>, Hanoverae 1693, abgedruckt.</ref> Hisce post mei recommendationem omnem prosperitatem a Bono Deo intime apprecans sum et ero Ornatissimae vestrae dominationis Addictissimus servus P. Georgius Fäch.

Ex Eremo B. V. M.<ref>Einsiedeln</ref> 17. Augusti Anno 1695.

</letter>

我找到了这个解决方案:XSLT - add <p> into text strings instead of \n

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>

<xsl:template match="letter">

    <xsl:analyze-string select="." regex="&#xa;&#xa;">
            <xsl:non-matching-substring>
                <p>
                    <xsl:value-of select="." disable-output-escaping="yes" />
                </p>
            </xsl:non-matching-substring>
        </xsl:analyze-string>

</xsl:template>

这已经接近我想要的但问题是<xsl:value-of select="." disable-output-escaping="yes" />不保留任何标记。最后,我只有段落标签包含文本内容(所有标签都被删除)。

我想到了身份转换,但我不允许使用<xsl:apply-templates />代替<xsl:value-of select=".">

我想要制作的是:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE letter SYSTEM "../Schema_and_DTD/entities.dtd">
<letter xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../Schema_and_DTD/letter.xsd" page_id="940" title="1695-08-17_Faeh_Georg-Bernoulli_Johann_I" catalogue_id="000055848">

<p><facsimile src=""/> Colendissime ac ornatissime Domine etc.</p>

<p>Colendissimae dominationi Vestrae gratificandi ergo, exactissima diligentia tum in Bibliotheca nostra Conventuali, tum in Bibliopolio mihi commisso perquisivi Chronicon Joannis Vitodurani<ref><i>Die Chronik Johanns von Winterthur (Chronica Iohannis Vitodurani)</i>, herausgegeben von F. Baethgen und C. Brun in: <i>Scriptores rerum Germanicarum</i>, Nova series 3, Berlin 1924.</ref>, sed nihil de eo repertum fuit.<ref>Leibniz hat die Chronik des Johannes von Winterthur später aus Bremen erhalten und in seinem <i>Codex juris gentium diplomaticus</i>, Hanoverae 1693, abgedruckt.</ref> Hisce post mei recommendationem omnem prosperitatem a Bono Deo intime apprecans sum et ero Ornatissimae vestrae dominationis Addictissimus servus P. Georgius Fäch.</p>

<p>Ex Eremo B. V. M.<ref>Einsiedeln</ref> 17. Augusti Anno 1695.</p>

</letter>  

有没有办法获得整个不匹配的子字符串(包括标记),只是用段落标记包装它?

2 个答案:

答案 0 :(得分:2)

我认为你需要两个通道,一个插入某个元素(我已选择br但当然你可以选择任何不会干扰你现有词汇的东西),第二个使用{{1 }} for-each-group

group-starting-with="br"

这应该给你一个想法,我认为你需要一些空白调整。

答案 1 :(得分:2)

这个问题有两种方法。

一种方法是在文本中添加标记,然后使用分组等工具来处理标记所指示的结构:这是Martin正在使用的方法。

第二种方法是将现有标记转换为某种文本注释,然后使用analyze-string来操作文本,然后将文本注释转换回标记。

使用XSLT 3.0,可以通过将<p>元素的内容序列化为字符串(使用fn:serialize()),然后应用xsl:analyze-string,然后解析结果来实现第二种方法使用fn:parse-xml()到树中的节点。