xml_to_json 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +14 -0
- data/Gemfile.lock +36 -0
- data/Rakefile +57 -0
- data/Readme.textile +89 -0
- data/VERSION +1 -0
- data/lib/xml_to_json.rb +17 -0
- data/lib/xml_to_json/string.rb +7 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/string_spec.rb +22 -0
- data/spec/xml_to_json_spec.rb +21 -0
- data/vendor/xml2json-xslt/COPYRIGHT.txt +26 -0
- data/vendor/xml2json-xslt/README.txt +107 -0
- data/vendor/xml2json-xslt/test-js.xml +53 -0
- data/vendor/xml2json-xslt/test-js2.xml +2 -0
- data/vendor/xml2json-xslt/test-json.xml +49 -0
- data/vendor/xml2json-xslt/test-json2.xml +2 -0
- data/vendor/xml2json-xslt/xml2js.xslt +360 -0
- data/vendor/xml2json-xslt/xml2json-patched.xslt +178 -0
- data/vendor/xml2json-xslt/xml2json.xslt +177 -0
- data/xml_to_json.gemspec +106 -0
- metadata +336 -0
data/Gemfile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem 'nokogiri'
|
4
|
+
|
5
|
+
group :development do
|
6
|
+
gem 'yajl-ruby'
|
7
|
+
gem 'activesupport', "3.0.1"
|
8
|
+
gem 'builder'
|
9
|
+
|
10
|
+
gem "rspec", "2.1.0"
|
11
|
+
gem "bundler", "~> 1.0.0"
|
12
|
+
gem "jeweler", "~> 1.5.0.pre6"
|
13
|
+
gem "rcov", ">= 0"
|
14
|
+
end
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (3.0.1)
|
5
|
+
builder (2.1.2)
|
6
|
+
diff-lcs (1.1.2)
|
7
|
+
git (1.2.5)
|
8
|
+
jeweler (1.5.0.pre6)
|
9
|
+
bundler (~> 1.0.0)
|
10
|
+
git (>= 1.2.5)
|
11
|
+
rake
|
12
|
+
nokogiri (1.4.3.1)
|
13
|
+
rake (0.8.7)
|
14
|
+
rcov (0.9.9)
|
15
|
+
rspec (2.1.0)
|
16
|
+
rspec-core (~> 2.1.0)
|
17
|
+
rspec-expectations (~> 2.1.0)
|
18
|
+
rspec-mocks (~> 2.1.0)
|
19
|
+
rspec-core (2.1.0)
|
20
|
+
rspec-expectations (2.1.0)
|
21
|
+
diff-lcs (~> 1.1.2)
|
22
|
+
rspec-mocks (2.1.0)
|
23
|
+
yajl-ruby (0.7.8)
|
24
|
+
|
25
|
+
PLATFORMS
|
26
|
+
ruby
|
27
|
+
|
28
|
+
DEPENDENCIES
|
29
|
+
activesupport (= 3.0.1)
|
30
|
+
builder
|
31
|
+
bundler (~> 1.0.0)
|
32
|
+
jeweler (~> 1.5.0.pre6)
|
33
|
+
nokogiri
|
34
|
+
rcov
|
35
|
+
rspec (= 2.1.0)
|
36
|
+
yajl-ruby
|
data/Rakefile
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "xml_to_json"
|
16
|
+
gem.homepage = "http://github.com/mtodd/xml_to_json"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{Transforms XML to JSON}
|
19
|
+
gem.description = %Q{Transforms a string of XML into a string of JSON}
|
20
|
+
gem.email = "chiology@gmail.com"
|
21
|
+
gem.authors = ["Matt Todd"]
|
22
|
+
|
23
|
+
gem.add_runtime_dependency 'nokogiri', '1.4.3.1'
|
24
|
+
|
25
|
+
gem.add_development_dependency 'yajl-ruby', '0.7.8'
|
26
|
+
gem.add_development_dependency 'activesupport', '3.0.1'
|
27
|
+
gem.add_development_dependency 'builder', '2.1.2'
|
28
|
+
|
29
|
+
gem.add_development_dependency 'rspec', '2.1.0'
|
30
|
+
gem.add_development_dependency 'bundler', '~> 1.0.0'
|
31
|
+
gem.add_development_dependency 'jeweler', '~> 1.5.0.pre6'
|
32
|
+
gem.add_development_dependency 'rcov', '>= 0'
|
33
|
+
end
|
34
|
+
Jeweler::RubygemsDotOrgTasks.new
|
35
|
+
|
36
|
+
require 'rspec/core'
|
37
|
+
require 'rspec/core/rake_task'
|
38
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
39
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
40
|
+
end
|
41
|
+
|
42
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
43
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
44
|
+
spec.rcov = true
|
45
|
+
end
|
46
|
+
|
47
|
+
task :default => :spec
|
48
|
+
|
49
|
+
require 'rake/rdoctask'
|
50
|
+
Rake::RDocTask.new do |rdoc|
|
51
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
52
|
+
|
53
|
+
rdoc.rdoc_dir = 'rdoc'
|
54
|
+
rdoc.title = "xml_to_json #{version}"
|
55
|
+
rdoc.rdoc_files.include('README*')
|
56
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
57
|
+
end
|
data/Readme.textile
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
h1. XML to JSON
|
2
|
+
|
3
|
+
Transforms strings of XML to JSON using a simple XSLT.
|
4
|
+
|
5
|
+
h2. Usage
|
6
|
+
|
7
|
+
<pre>
|
8
|
+
require 'xml_to_json'
|
9
|
+
|
10
|
+
puts XmlToJson.transform(<<-XML)
|
11
|
+
<items>
|
12
|
+
<item>
|
13
|
+
<id>1</id>
|
14
|
+
<name>Foo</name>
|
15
|
+
</item>
|
16
|
+
<item>
|
17
|
+
<id>2</id>
|
18
|
+
<name>Bar</name>
|
19
|
+
</item>
|
20
|
+
</items>
|
21
|
+
XML
|
22
|
+
</pre>
|
23
|
+
|
24
|
+
Transforms into:
|
25
|
+
|
26
|
+
<pre>
|
27
|
+
{"items":[
|
28
|
+
{
|
29
|
+
"id":1,
|
30
|
+
"name":"Foo"
|
31
|
+
},
|
32
|
+
{
|
33
|
+
"id":2,
|
34
|
+
"name":"Bar"
|
35
|
+
}
|
36
|
+
]}
|
37
|
+
</pre>
|
38
|
+
|
39
|
+
Or:
|
40
|
+
|
41
|
+
<pre>
|
42
|
+
require 'xml_to_json/string'
|
43
|
+
|
44
|
+
xml.to_json
|
45
|
+
</pre>
|
46
|
+
|
47
|
+
h2. TODO
|
48
|
+
|
49
|
+
* Nokogiri::Document#to_json
|
50
|
+
|
51
|
+
h2. Contributing to xml_to_json
|
52
|
+
|
53
|
+
# Fork on GitHub
|
54
|
+
# Write a failing spec
|
55
|
+
# OPTIONAL: Make the failing spec pass
|
56
|
+
# Send a pull request
|
57
|
+
|
58
|
+
Bonus points for topic branches.
|
59
|
+
|
60
|
+
If you prove something is broken, I'll be happy to try to fix it. A failing
|
61
|
+
spec is sufficient!
|
62
|
+
|
63
|
+
The Rakefile, version, and history files are generated by Jeweler. Don't modify
|
64
|
+
them or I won't accept your patch. (Exceptions are made when the situation is
|
65
|
+
exceptional.)
|
66
|
+
|
67
|
+
h2. License
|
68
|
+
|
69
|
+
The MIT License
|
70
|
+
|
71
|
+
Copyright (c) 2010 Matt Todd.
|
72
|
+
|
73
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
74
|
+
of this software and associated documentation files (the "Software"), to deal
|
75
|
+
in the Software without restriction, including without limitation the rights
|
76
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
77
|
+
copies of the Software, and to permit persons to whom the Software is
|
78
|
+
furnished to do so, subject to the following conditions:
|
79
|
+
|
80
|
+
The above copyright notice and this permission notice shall be included in
|
81
|
+
all copies or substantial portions of the Software.
|
82
|
+
|
83
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
84
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
85
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
86
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
87
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
88
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
89
|
+
THE SOFTWARE.
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.0
|
data/lib/xml_to_json.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module XmlToJson
|
4
|
+
module_function
|
5
|
+
|
6
|
+
def transform(xml)
|
7
|
+
stylesheet.transform(Nokogiri::XML(xml)).text
|
8
|
+
end
|
9
|
+
|
10
|
+
def root
|
11
|
+
@root ||= Pathname.new(__FILE__).dirname.parent
|
12
|
+
end
|
13
|
+
|
14
|
+
def stylesheet
|
15
|
+
@stylesheet ||= Nokogiri::XSLT(root.join('vendor', 'xml2json-xslt', 'xml2json-patched.xslt').read)
|
16
|
+
end
|
17
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
2
|
+
require 'rubygems'
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'xml_to_json'
|
5
|
+
|
6
|
+
require 'rspec'
|
7
|
+
|
8
|
+
require 'active_support/core_ext/array/conversions'
|
9
|
+
require 'active_support/core_ext/hash/conversions'
|
10
|
+
require 'yajl/json_gem'
|
data/spec/string_spec.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'xml_to_json/string'
|
3
|
+
|
4
|
+
describe "String#to_json" do
|
5
|
+
before :each do
|
6
|
+
@source = [
|
7
|
+
{
|
8
|
+
:id => 1,
|
9
|
+
:name => "Foo"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
:id => 2,
|
13
|
+
:name => "Bar"
|
14
|
+
}
|
15
|
+
]
|
16
|
+
@xml = @source.to_xml(:root => "items")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should transform an XML string to JSON" do
|
20
|
+
@xml.to_json.should == {:items => @source}.to_json
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "XmlToJson" do
|
4
|
+
before :each do
|
5
|
+
@source = [
|
6
|
+
{
|
7
|
+
:id => 1,
|
8
|
+
:name => "Foo"
|
9
|
+
},
|
10
|
+
{
|
11
|
+
:id => 2,
|
12
|
+
:name => "Bar"
|
13
|
+
}
|
14
|
+
]
|
15
|
+
@xml = @source.to_xml(:root => "items")
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should transform an array of items into a hash of items" do
|
19
|
+
XmlToJson.transform(@xml).should == {:items => @source}.to_json
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
Copyright (c) 2006, Doeke Zanstra
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without modification,
|
5
|
+
are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
Redistributions of source code must retain the above copyright notice, this
|
8
|
+
list of conditions and the following disclaimer. Redistributions in binary
|
9
|
+
form must reproduce the above copyright notice, this list of conditions and the
|
10
|
+
following disclaimer in the documentation and/or other materials provided with
|
11
|
+
the distribution.
|
12
|
+
|
13
|
+
Neither the name of the dzLib nor the names of its contributors may be used to
|
14
|
+
endorse or promote products derived from this software without specific prior
|
15
|
+
written permission.
|
16
|
+
|
17
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
18
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
19
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
20
|
+
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
21
|
+
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
22
|
+
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
23
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
24
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
25
|
+
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
26
|
+
THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,107 @@
|
|
1
|
+
====== xml2json.xslt ======
|
2
|
+
|
3
|
+
version 0.3, Copyright (c) 2006, Doeke Zanstra, see COPYRIGHT.txt
|
4
|
+
|
5
|
+
xml2json.xslt is a XSLT 1.0 stylesheet to transform arbitrary XML to JSON. There is also a version for javascript. The workings are demonstrated with the accompanied xml files. The target of this library is to create javascript-like JSON, not XML-like JSON, like the BadgerFish convention (see Resources).
|
6
|
+
|
7
|
+
The downside is it won't translate all markup, and there's a chance the JSON is invalid. However, if you control the XML, you will enjoy the merits of javascript. Enjoy ;-)
|
8
|
+
|
9
|
+
I will call this the Parker convention, after the comic Parker & Badger by Cuadrado. I can really recommend the comic, also in relation to this work and the BadgerFish convention.
|
10
|
+
|
11
|
+
====== Using ======
|
12
|
+
|
13
|
+
You can load the xml files in your browser (Firefox/Camino work, Safari doesn't, Internet Explorer 6 works, except test-js.xml). On windows, you can also try the commandline Msxsl utility (see resources). And of course you can fire up your favorite transformation engine.
|
14
|
+
|
15
|
+
====== Translation JSON ======
|
16
|
+
|
17
|
+
1. The root element will be absorbed, for there is only one
|
18
|
+
<root>test</root>
|
19
|
+
becomes
|
20
|
+
"test"
|
21
|
+
|
22
|
+
2. Element names become object properties:
|
23
|
+
<root><name>Xml</name><encoding>ASCII</encoding></root>
|
24
|
+
becomes
|
25
|
+
{"name":"Xml","encoding":"ASCII"}
|
26
|
+
|
27
|
+
3. Numbers are recognized (integers and decimals):
|
28
|
+
<root><age>12</age><height>1.73</height></root>
|
29
|
+
becomes
|
30
|
+
{"age":12,"height":1.73}
|
31
|
+
|
32
|
+
4. Booleans are recognized case insensitive:
|
33
|
+
<root><checked>True</checked><answer>FALSE</answer></root>
|
34
|
+
becomes
|
35
|
+
{"checked":true,"answer":false}
|
36
|
+
|
37
|
+
5. Strings are escaped:
|
38
|
+
<root>Quote: " New-line:
|
39
|
+
</root>
|
40
|
+
becomes
|
41
|
+
"Quote: \" New-line:\n"
|
42
|
+
|
43
|
+
6. Empty elements will become null:
|
44
|
+
<root><nil/><empty></empty></root>
|
45
|
+
becomes
|
46
|
+
{"nil":null,"empty":null}
|
47
|
+
|
48
|
+
7. If all sibling elements have the same name, they become an array
|
49
|
+
<root><item>1</item><item>2</item><item>three</item></root>
|
50
|
+
becomes
|
51
|
+
[1,2,"three"]
|
52
|
+
|
53
|
+
8. Mixed mode text-nodes, comments and attributes get absorbed:
|
54
|
+
<root version="1.0">testing<!--comment--><element test="true">1</element></root>
|
55
|
+
becomes
|
56
|
+
{element:true}
|
57
|
+
|
58
|
+
9. Namespaces get absorbed, and prefixes will just be part of the property name:
|
59
|
+
<root xmlns:ding="http://zanstra.com/ding"><ding:dong>binnen</ding:dong></root>
|
60
|
+
becomes
|
61
|
+
{"ding:dong":"binnen"}
|
62
|
+
|
63
|
+
====== Translation JS extra ======
|
64
|
+
|
65
|
+
All the same as the JSON translation, but with these extra's:
|
66
|
+
|
67
|
+
1. Property names are only escaped when necessary
|
68
|
+
<root><while>true</while><wend>false</wend><only-if/></root>
|
69
|
+
becomes
|
70
|
+
{"while":true,wend:false,"only-if":null}
|
71
|
+
|
72
|
+
2. Within a string, closing elements "</" are escaped as "<\/"
|
73
|
+
<root><![CDATA[<script>alert("YES");</script>]]></root>
|
74
|
+
becomes
|
75
|
+
{script:"<script>alert(\"YES\")<\/script>"}
|
76
|
+
|
77
|
+
3. Dates are created as new Date() objects
|
78
|
+
<root>2006-12-25</root>
|
79
|
+
becomes
|
80
|
+
new Date(2006,12-1,25)
|
81
|
+
|
82
|
+
4. Attributes and comments are shown as comments (for testing-purposes):
|
83
|
+
<!--testing--><root><test version="1.0">123</test></root>
|
84
|
+
becomes
|
85
|
+
/*testing*/{test/*@version="1.0"*/:123}
|
86
|
+
|
87
|
+
5. A bit of indentation is done, to keep things ledgible
|
88
|
+
|
89
|
+
====== Plans ======
|
90
|
+
|
91
|
+
I don't really have much plans with this library. It was mere a result of learning XSLT and XPath better. However, I will perform bug-fixes. Issues I might address, if I can find a satisfactory solution:
|
92
|
+
|
93
|
+
- convert attributes to properties in some way
|
94
|
+
|
95
|
+
- handle siblings with duplicate names, when there are also other names:
|
96
|
+
<root><item>1</item><item>2</item><name>test</name></root>
|
97
|
+
becomes (faulty JSON)
|
98
|
+
{"item":1,"item":2,"name":"test"}
|
99
|
+
|
100
|
+
====== Resources ======
|
101
|
+
|
102
|
+
* Xml: http://www.w3.org/TR/xml/
|
103
|
+
* Xslt: http://www.w3.org/TR/xslt
|
104
|
+
* XPath: http://www.w3.org/TR/xpath
|
105
|
+
* Json: http://www.json.org
|
106
|
+
* BadgerFish: http://badgerfish.ning.com/
|
107
|
+
* Msxsl: http://www.microsoft.com/downloads/details.aspx?FamilyId=2FB55371-C94E-4373-B0E9-DB4816552E41&displaylang=en
|
@@ -0,0 +1,53 @@
|
|
1
|
+
<?xml-stylesheet type="text/xsl" href="xml2js.xslt"?>
|
2
|
+
<!--
|
3
|
+
Test XML markup for converting xml to JS using XSLT.
|
4
|
+
By Doeke Zanstra, 2006
|
5
|
+
-->
|
6
|
+
<root version="1.0" xmlns:ding="http://zanstra.com/ding">
|
7
|
+
this text should be ignored
|
8
|
+
<birthdate>2006-11-14</birthdate>
|
9
|
+
<appointment>2006-11-14T12:30</appointment>
|
10
|
+
<appointment>2006-11-14T12:30:00</appointment>
|
11
|
+
<script><![CDATA[<script>alert("YES")</script>]]></script>
|
12
|
+
<positive>123</positive>
|
13
|
+
<negative>-12</negative>
|
14
|
+
<zero>0</zero>
|
15
|
+
<fixed>10.25</fixed>
|
16
|
+
<fixed-neg>-10.25</fixed-neg>
|
17
|
+
<padded_zero>01</padded_zero>
|
18
|
+
<ding:dong-dang.dung>Namespaced element with dash and dot</ding:dong-dang.dung>
|
19
|
+
<yo123-ho456/>
|
20
|
+
<string>Zooi</string>
|
21
|
+
<string>Tab Text</string>
|
22
|
+
<string>Quote "test"</string>
|
23
|
+
<string>Backslash \ test</string>
|
24
|
+
<string>Quote " en \ test</string>
|
25
|
+
<string>"Begin/end quote"</string>
|
26
|
+
<escape>Line one (één in Dutch)
|
27
|
+
Line two: tab
|
28
|
+
He said: "Much fun with a €"
|
29
|
+
More unicode†</escape>
|
30
|
+
<int>123</int>
|
31
|
+
<float>-12.123</float>
|
32
|
+
<exp>-1.234e5</exp>
|
33
|
+
<boolean>true</boolean>
|
34
|
+
<nil/>
|
35
|
+
<empty></empty>
|
36
|
+
<object test="true" attributes="are commented">
|
37
|
+
<zooi>jaja</zooi>
|
38
|
+
<zut>frot</zut>
|
39
|
+
</object>
|
40
|
+
<array>
|
41
|
+
<item/>
|
42
|
+
<item>true</item>
|
43
|
+
<item>2</item>
|
44
|
+
<item>3</item>
|
45
|
+
<item>4</item>
|
46
|
+
<item>5</item>
|
47
|
+
<item>six</item>
|
48
|
+
<item>
|
49
|
+
<key>item</key>
|
50
|
+
<value>7</value>
|
51
|
+
</item>
|
52
|
+
</array>
|
53
|
+
</root>
|