如何使Builder不对'śćż'和其他此类字符进行编码。 我想要的是'całość'字面上打印在XML文档中。 例如:
xml.instruct! :xml, :version => '1.0', :encoding => 'utf-8'
xml.Trader( :'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance",
:'xmlns:xsd' => "http://www.w3.org/2001/XMLSchema") do
xml.Informacje do
xml.RodzajPaczki 'całość'
xml.Program 'mine'
xml.WersjaProgramu '1.0'
end
end
输出:
<?xml version="1.0" encoding="utf-8"?>
<Trader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Informacje>
<RodzajPaczki>całość</RodzajPaczki>
<Program>mine</Program>
<WersjaProgramu>1.0</WersjaProgramu>
</Informacje>
</Trader>
całość
应为całość
。
我看到像xml.RodzajPaczki {|t| t << 'całość' }
这样的伪解决方案,但它无法正常工作。它突然出现在文件左侧的'całość'。
答案 0 :(得分:9)
以下是发生的事情。正如我们所知,默认情况下,Builder将转义非{ASCII}字符,如całość
中的字符。你还提到了一种可能的解决方法,那就是:
xml.RodzajPaczki {|t| t << 'całość' }
不幸的是,当你将一个块传递给RodzajPaczki
元素时,Builder假定会有一些内部xml,所以它会添加一个新行并应用缩进。当然在我们的例子中只有内部文本而没有xml,所以我们得到一些难看的输出,如:
<RodzajPaczki>
całość </RodzajPaczki>
有一种简单的方法可以解决这个问题。首先是简单的方法。
将缩进配置为零
然后你可以使用上面的修复xml.RodzajPaczki {|t| t << 'całość' }
一切都会按预期工作,但输出不会很漂亮,它实际上都是一行:
<?xml version="1.0" encoding="UTF-8"?><Trader xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Informacje><RodzajPaczki>całość</RodzajPaczki><Program>mine</Program><WersjaProgramu>1.0</WersjaProgramu></Informacje></Trader>
如果您希望格式化得很好,可以通过外部漂亮的打印机运行。
如果您只是必须具有漂亮的打印输出并且不想进行转义,我们需要稍微修补Builder。这是解决此问题的难点。
修补构建器
我们需要修补XmlMarkup
对象的初始值设定项,以添加额外的选项:escape
。同时我们修补XmlBase
对象以将此新选项作为参数。我们将此新选项默认为true
,以维护默认行为。然后,我们在text!
上修补XmlBase
方法,以使用我们的新选项来决定是否应该删除非文本。这是它的样子:
module Builder
class XmlBase
def initialize(indent=0, initial=0, encoding='utf-8', escape=true)
@indent = indent
@level = initial
@encoding = encoding.downcase
@escape = escape
end
def text!(text)
if @escape
_text(_escape(text))
else
_text(text)
end
end
end
class XmlMarkup
def initialize(options={})
indent = options[:indent] || 0
margin = options[:margin] || 0
encoding = options[:encoding] || 'utf-8'
escape = options[:escape]
if escape == nil
escape = true
end
super(indent, margin, encoding, escape)
@target = options[:target] || ""
end
end
end
我们现在可以通过以下方式使用我们新修补的构建器( 注意,当我们构造XmlMarkup
对象时,我们传递了新的:escape
选项,其值为{ {1}} 强>):
false
输出如下:
xml = Builder::XmlMarkup.new(:target=>STDOUT, :indent=>3, :encoding => 'utf-8', :escape => false)
xml.instruct! :xml, :version => '1.0', :encoding => 'UTF-8'
xml.Trader(:'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance", :'xmlns:xsd' => "http://www.w3.org/2001/XMLSchema") do
xml.Informacje do
xml.RodzajPaczki('całość')
xml.Program('mine')
xml.WersjaProgramu('1.0')
end
end
根据需要,文本不会被转义。请注意,修补程序会将此非转义行为应用于所有文本,因此,如果您只希望某些文本不转义而其他文本仍然转义,则需要更大程度地修补构建器。
答案 1 :(得分:0)
我无法使用我的设置复制此内容。您使用的是什么版本的ruby / rails / builder?
答案 2 :(得分:0)
我可以毫无问题地输出“całość”(Ruby 1.9.2,Builder 3.0.0)。
手册页http://builder.rubyforge.org/建议将$KCODE
设置为'UTF8'
(参见本页末尾),但我认为这适用于Ruby 1.8。
我的文件中包含的内容如下:
#!/usr/bin/ruby -wE UTF-8:UTF-8
# encoding: UTF-8
require 'builder'
...
xml = Builder::XmlMarkup.new( :target => target, :indent => 2 )
xml.instruct! :xml, :version => '1.0', :encoding => 'UTF-8'
...
答案 3 :(得分:0)
Rails ticket #1446中的评论表明这可以在Builder 3.0.0中修复。不过我自己还没试过。