Encode/decode XML entities.
When lexing XML entities such as & and < these sequences are now
converted into their "actual" forms. In turn, Oga::XML::Text#to_xml ensures they
are encoded when the method is called.
Performance wise this puts some strain on the lexer, for every T_TEXT/T_STRING
node now potentially has to have its content modified. In the benchmark
xml/lexer/string_average_bench.rb the average processing time is now about the
same as before the improvements made in
8db77c0a09. I was hoping that the lexer would
still be a bit faster, but alas this is not the case. Doing this in native code
would be a nightmare as C doesn't have a proper string replacement function. I'm
not old/sadistic enough to write on myself just yet.
This fixes #49
This commit is contained in:
1 parent
3307e2f4d2
commit
5f7256eb8f
9 files changed
+164
-8
No files matched your search
@@ -78,6 +78,12 @@ describe Oga::XML::Attribute do
|
||||
|
||||
attr.to_xml.should == 'xmlns:class=""'
|
||||
end
|
||||
|
||||
example 'convert special characters to XML entities' do
|
||||
attr = described_class.new(:name => 'href', :value => '&<>')
|
||||
|
||||
attr.to_xml.should == 'href="&<>"'
|
||||
end
|
||||
end
|
||||
|
||||
context '#inspect' do
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Oga::XML::Entities do
|
||||
context 'decode' do
|
||||
example 'decode & into &' do
|
||||
described_class.decode('&').should == '&'
|
||||
end
|
||||
|
||||
example 'decode < into <' do
|
||||
described_class.decode('<').should == '<'
|
||||
end
|
||||
|
||||
example 'decode > into >' do
|
||||
described_class.decode('>').should == '>'
|
||||
end
|
||||
end
|
||||
|
||||
context 'encode' do
|
||||
example 'encode & as &' do
|
||||
described_class.encode('&').should == '&'
|
||||
end
|
||||
|
||||
example 'encode < as <' do
|
||||
described_class.encode('<').should == '<'
|
||||
end
|
||||
|
||||
example 'encode > as >' do
|
||||
described_class.encode('>').should == '>'
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,49 @@
|
||||
require 'spec_helper'
|
||||
|
||||
describe Oga::XML::Lexer do
|
||||
context 'converting XML entities in text tokens' do
|
||||
example 'convert & into &' do
|
||||
lex('&').should == [[:T_TEXT, '&', 1]]
|
||||
end
|
||||
|
||||
example 'convert < into <' do
|
||||
lex('<').should == [[:T_TEXT, '<', 1]]
|
||||
end
|
||||
|
||||
example 'convert > into >' do
|
||||
lex('>').should == [[:T_TEXT, '>', 1]]
|
||||
end
|
||||
end
|
||||
|
||||
context 'converting XML entities in string tokens' do
|
||||
example 'convert & into &' do
|
||||
lex('<foo class="&" />').should == [
|
||||
[:T_ELEM_START, nil, 1],
|
||||
[:T_ELEM_NAME, 'foo', 1],
|
||||
[:T_ATTR, 'class', 1],
|
||||
[:T_STRING, '&', 1],
|
||||
[:T_ELEM_END, nil, 1]
|
||||
]
|
||||
end
|
||||
|
||||
example 'convert < into <' do
|
||||
lex('<foo class="<" />').should == [
|
||||
[:T_ELEM_START, nil, 1],
|
||||
[:T_ELEM_NAME, 'foo', 1],
|
||||
[:T_ATTR, 'class', 1],
|
||||
[:T_STRING, '<', 1],
|
||||
[:T_ELEM_END, nil, 1]
|
||||
]
|
||||
end
|
||||
|
||||
example 'convert > into >' do
|
||||
lex('<foo class=">" />').should == [
|
||||
[:T_ELEM_START, nil, 1],
|
||||
[:T_ELEM_NAME, 'foo', 1],
|
||||
[:T_ATTR, 'class', 1],
|
||||
[:T_STRING, '>', 1],
|
||||
[:T_ELEM_END, nil, 1]
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -15,12 +15,16 @@ describe Oga::XML::Text do
|
||||
end
|
||||
|
||||
context '#to_xml' do
|
||||
before do
|
||||
@instance = described_class.new(:text => 'foo')
|
||||
example 'generate the corresponding XML' do
|
||||
node = described_class.new(:text => 'foo')
|
||||
|
||||
node.to_xml.should == 'foo'
|
||||
end
|
||||
|
||||
example 'generate the corresponding XML' do
|
||||
@instance.to_xml.should == 'foo'
|
||||
example 'encode special characters as XML entities' do
|
||||
node = described_class.new(:text => '&<>')
|
||||
|
||||
node.to_xml.should == '&<>'
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in new issue
Block a user