2016-09-30 29 views
0

我想處理一個XML文件,以便在一行中的兩個換行符變成段落(就像在LaTeX中)之前或之後站立的任何東西。使用xsl:analyze-string並保留標記(就像在標識轉換中一樣)

這是源文件:

<?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

我想你需要兩個通道,一個插入一個特定元素(我已經選擇br當然你可以選擇任何不與現有的詞彙干擾),第二使用for-each-groupgroup-starting-with="br"

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> 

    <xsl:output indent="yes"/> 

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

    <xsl:template match="letter"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <xsl:variable name="letter-with-line-breaks"> 
       <xsl:apply-templates select="." mode="breaks"/> 
      </xsl:variable> 
      <xsl:for-each-group select="$letter-with-line-breaks/letter/node()" group-starting-with="br"> 
       <p> 
        <xsl:apply-templates select="current-group()[not(self::br)]"/> 
       </p> 
      </xsl:for-each-group> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="letter//text()" mode="breaks"> 
     <xsl:analyze-string select="." regex="&#10;&#10;"> 
      <xsl:matching-substring> 
       <br/> 
      </xsl:matching-substring> 
      <xsl:non-matching-substring> 
       <xsl:value-of select="."/> 
      </xsl:non-matching-substring> 
     </xsl:analyze-string> 
    </xsl:template> 
</xsl:transform> 

這應該給你一個想法,我認爲你需要一些空白的調整。

+0

謝謝!我會嘗試的! – user130685

+0

我其實只期望段落的直接子女。應該說:而不是? – user130685

+0

是的,我覺得''如果您只對'letter'元素的子節點中的換行符感興趣,我想我當前的分組建議也只適用於這種情況,所以改變模式匹配=匹配=「信/文()」模式=「休息」。 –

2

有兩種解決此問題的方法。

其中之一是爲文本添加標記,然後使用分組等設施來處理由標記指示的結構:這就是Martin正在使用的方法。

第二種方法是將現有標記轉換爲某種文本標註,然後使用analyze-string操縱文本,然後將文本標註轉換爲標記。

使用XSLT 3.0,第二種方法可以通過<p>元素的內容序列化到一個字符串(使用fn:serialize()),然後施加xsl:analyze-string,然後使用fn:parse-xml()在樹解析結果返回給節點來實現。

相關問題