2016-03-27 59 views
2

這個問題是間歇性發生的,也就是說我沒有這個問題執行了很多xslt轉換,然後它在我最近的xslt轉換過程中突然出現。xslt將utf-8字符轉換爲不同的編碼

我有大量的HTML輸入文件與類似於以下a.html的結構:

<html> 
    <body> 
    <div class="wrd"> 
     <div class="wrd-id">5</div> 
     <div class="wrd-wrd">address</div> 
     <div class="wrd-ipa">əˈdres,ˈaˌdres</div> 
    </div> 
    <div class="a">...</div> 
    </body> 
</html> 

當我檢查輸入文件,我得到以下結果的編碼:

file -I a.html 
a.html: text/html; charset=utf-8 

我改造的html文件,並顯示類似以下a.xslt的XSLT:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > 
<xsl:output omit-xml-declaration="yes" indent="yes" encoding="UTF-8" /> 
<xsl:strip-space elements="*" /> 

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

<xsl:template match="div[@class='a']" > 
    <xsl:apply-templates select="*|node()" /> 
</xsl:template> 

</xsl:stylesheet> 

我使用類似於以下a.sh腳本:

#!/bin/bash 
xsltproc --html a.xslt a.html > b.html 

更完整的bash腳本如下:

#!/bin/bash 
xsltproc --html a.xslt a.html \ 
| hxnormalize -x -l 1024 \ 
| sed '/^$/d' \ 
> b.html 

而且我得到以下結果b.html:

<html> 
    <body> 
    <div class="wrd"> 
     <div class="wrd-id">5</div> 
     <div class="wrd-wrd">address</div> 
     <div class="wrd-ipa">ÉËdres,ËaËdres</div> 
    </div> 
    ... 
    </body> 
</html> 

事實上,我的輸出包含一些顛倒的問號,我無法在這裏複製和粘貼。請參考下面

non UTF-8 output

圖片屬於UTF-8字符集輸入的字符被改造成別的東西。

當我檢查文件b.html我得到以下結果的編碼:

file -I b.html 
b.html: text/html; charset=utf-8 

我怎樣才能防止XSLT轉換,從一個編碼改變我的角色到另一個?

更新1

通過從xsltproc的命令選項 「--html」,問題得到解決。但是我仍然不確定爲什麼。

#!/bin/bash 
xsltproc a.xslt a.html > b.html 

UPDATE 2

看來,輸入文件被解釋爲ASCII或ISO-8859-1代替的UTF-8。我已經插入在輸入a.html下面的頭:

<head> 
    <meta charset="UTF-8"> 
    <meta http-equiv="content-type" content="text/html"> 
    </head> 

然而輸出b.html仍然是相同的。

更新3

我有更新a.xslt以下幾點:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="html" version="4.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

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

</xsl:stylesheet> 

請注意不同的xsl:輸出線

這將創建灣HTML同樣的問題,但第一行給出了以下的html聲明:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 

背後或許這裏還有就是ASCII或ISO-8859-1來解釋輸入文件的原因。

回答

2

SOLUTION

xsltproc的拾取從META Content-Type頭的HTML輸入文件的文件編碼。當這樣的頭文件不存在時,它可能會錯誤地假定文件編碼,並在讀取文件時屠殺文件。

我已經插在輸入a.html以下標題:

<head> 
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 
</head> 

而且我已經運行下面的bash腳本:

#!/bin/bash 
xsltproc --html a.xslt a.html > b.html 

的XSLT a.xslt如下:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="html" version="4.0" encoding="UTF-8" indent="yes" /> 
<xsl:strip-space elements="*"/> 

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

</xsl:stylesheet> 

並且輸出文件b.html最終如預期的那樣:

<html> 
    <body> 
    <div class="wrd"> 
     <div class="wrd-id">5</div> 
     <div class="wrd-wrd">address</div> 
     <div class="wrd-ipa">əˈdres,ˈaˌdres</div> 
    </div> 
    <div class="a">...</div> 
    </body> 
</html> 
+0

謝謝。一個非常有用的答案。 – Jagger

+0

事實上,我已經發現有'--encoding'參數,它允許您指定輸入文件的編碼,如果元信息不存在於html文件中。 – Jagger