2011-11-02 93 views
0

我試圖解析一個log4j.xml文件,編輯一些屬性並將其寫回。使用REXML保留DOCTYPE聲明

log4j.xml中有<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">聲明,但是當我將其寫回時,聲明更改爲<!DOCTYPE log4j>

我用xmlDoc = Document.new(File.new(file, 'r'))打開了解析文件,用xmlDoc.write(File.new(file, 'w'), 0)來寫。

我也試過用xmlDoc = Document.new(File.new(file, 'r'), { :raw => :all })打開。

有沒有辦法保留原始的DOCTYPE聲明?

非常感謝!

回答

0

恐怕用rexml這個用法是不可能的。看那個小結 - 這是發生在rexml

require 'rexml/source' 

LETTER = '[:alpha:]' 
COMBININGCHAR = '' 
EXTENDER = '' 
NCNAME_STR= "[#{LETTER}_:][-[:alnum:]._:#{COMBININGCHAR}#{EXTENDER}]*" 

IDENTITY = /^([!\*\w\-]+)(\s+#{NCNAME_STR})?(\s+["'](.*?)['"])?(\s+['"](.*?)["'])?/u 
DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um 

string = <<HERE 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" > 
<log4j:configuration> 
</log4j:configuration> 
HERE 
source = REXML::SourceFactory.create_from(string) 
md = source.match(DOCTYPE_PATTERN, true) 
identity = md[1] 
close = md[2] 
identity =~ IDENTITY 
name = $1 
pub_sys = $2.nil? ? nil : $2.strip 
long_name = $4.nil? ? nil : $4.strip 
uri = $6.nil? ? nil : $6.strip 
args = [ :start_doctype, name, pub_sys, long_name, uri ] 
p args # => [:start_doctype, "log4j", nil, nil, nil] 

正如你所看到的這個片段返回相同的結果的問題你的代碼的過程中「光版」。除此之外,您會看到代碼段中沒有可以改變此行爲的參數。

作爲解決方法,我建議您使用Nokogiri庫。在快速查看它可以正確地解析這種文檔類型:

require 'nokogiri' 

string = <<HERE 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" > 
<log4j:configuration> 
</log4j:configuration> 
HERE 

doc = Nokogiri::XML(string) 
puts doc.internal_subset.to_s 
# => <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">