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:
Yorick Peterse committed 2014-09-28 21:53:25 +02:00
1 parent 3307e2f4d2
commit 5f7256eb8f
9 files changed
+164 -8

No files matched your search

+6
View File
@@ -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="&amp;&lt;&gt;"'
end
end
context '#inspect' do
+31
View File
@@ -0,0 +1,31 @@
require 'spec_helper'
describe Oga::XML::Entities do
context 'decode' do
example 'decode &amp; into &' do
described_class.decode('&amp;').should == '&'
end
example 'decode &lt; into <' do
described_class.decode('&lt;').should == '<'
end
example 'decode &gt; into >' do
described_class.decode('&gt;').should == '>'
end
end
context 'encode' do
example 'encode & as &amp;' do
described_class.encode('&').should == '&amp;'
end
example 'encode < as &lt;' do
described_class.encode('<').should == '&lt;'
end
example 'encode > as &gt;' do
described_class.encode('>').should == '&gt;'
end
end
end
+49
View File
@@ -0,0 +1,49 @@
require 'spec_helper'
describe Oga::XML::Lexer do
context 'converting XML entities in text tokens' do
example 'convert &amp; into &' do
lex('&amp;').should == [[:T_TEXT, '&', 1]]
end
example 'convert &lt; into <' do
lex('&lt;').should == [[:T_TEXT, '<', 1]]
end
example 'convert &gt; into >' do
lex('&gt;').should == [[:T_TEXT, '>', 1]]
end
end
context 'converting XML entities in string tokens' do
example 'convert &amp; into &' do
lex('<foo class="&amp;" />').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 &lt; into <' do
lex('<foo class="&lt;" />').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 &gt; into >' do
lex('<foo class="&gt;" />').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
+8 -4
View File
@@ -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 == '&amp;&lt;&gt;'
end
end