xml-smart 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. data/AUTHORS +4 -0
  2. data/COPYING +504 -0
  3. data/README.rdoc +55 -0
  4. data/Rakefile +15 -0
  5. data/example/EXAMPLE.xml +18 -0
  6. data/example/xpath_visual.rb +54 -0
  7. data/lib/xml/XSDtoRNG.xsl +448 -0
  8. data/lib/xml/smart.rb +177 -0
  9. data/lib/xml/smart_dom.rb +118 -0
  10. data/lib/xml/smart_domattribute.rb +34 -0
  11. data/lib/xml/smart_domattributeset.rb +62 -0
  12. data/lib/xml/smart_domelement.rb +213 -0
  13. data/lib/xml/smart_domnamespace.rb +32 -0
  14. data/lib/xml/smart_domnamespaceset.rb +125 -0
  15. data/lib/xml/smart_domnodeset.rb +59 -0
  16. data/lib/xml/smart_domother.rb +16 -0
  17. data/lib/xml/smart_domtext.rb +25 -0
  18. data/lib/xml/smart_qname.rb +34 -0
  19. data/test/1.xml +1 -0
  20. data/test/2.xml +1 -0
  21. data/test/3.xml +1 -0
  22. data/test/EXAMPLE-NS.xml +18 -0
  23. data/test/EXAMPLE-NSE.xml +18 -0
  24. data/test/EXAMPLE.str.xml +6 -0
  25. data/test/EXAMPLE.str.xml.test +6 -0
  26. data/test/EXAMPLE.tmp.xml +4 -0
  27. data/test/EXAMPLE.tmp.xml.test +4 -0
  28. data/test/EXAMPLE.xml +17 -0
  29. data/test/HELLO-MORE.xml +1 -0
  30. data/test/HELLO.rng +9 -0
  31. data/test/HELLO.xml +8 -0
  32. data/test/HELLO.xsd +16 -0
  33. data/test/XSL_BASE.xml +17 -0
  34. data/test/XSL_BASE.xml.test +16 -0
  35. data/test/XSL_DOCUMENT.xml +48 -0
  36. data/test/concurrent.xml +1 -0
  37. data/test/smartrunner.rb +25 -0
  38. data/test/tc_add.rb +21 -0
  39. data/test/tc_basic.rb +108 -0
  40. data/test/tc_concurrent.rb +73 -0
  41. data/test/tc_copy.rb +41 -0
  42. data/test/tc_create.rb +32 -0
  43. data/test/tc_delete.rb +52 -0
  44. data/test/tc_move_elements.rb +24 -0
  45. data/test/tc_namespace_default.rb +70 -0
  46. data/test/tc_namespace_detailed.rb +44 -0
  47. data/test/tc_namespace_find.rb +22 -0
  48. data/test/tc_nested.rb +26 -0
  49. data/test/tc_qname.rb +30 -0
  50. data/test/tc_relaxng.rb +30 -0
  51. data/test/tc_set_or_replace.rb +57 -0
  52. data/test/tc_sort.rb +18 -0
  53. data/test/tc_string.rb +41 -0
  54. data/test/tc_todoc.rb +27 -0
  55. data/test/tc_write.rb +19 -0
  56. data/test/tc_xinclude.rb +26 -0
  57. data/test/tc_xmlschema.rb +30 -0
  58. data/test/tc_xpath.rb +16 -0
  59. data/test/tc_xpath_attrs.rb +24 -0
  60. data/test/tc_xpath_functions.rb +12 -0
  61. data/test/tc_xpath_root.rb +23 -0
  62. data/test/tc_xsl.rb +22 -0
  63. data/xml-smart.gemspec +26 -0
  64. metadata +201 -0
@@ -0,0 +1,34 @@
1
+ module XML
2
+ module Smart
3
+
4
+ class QName
5
+ def initialize(element); @element = element; end
6
+
7
+ def ==(str); @element.name == str; end
8
+ def ===(cls); self.is_a? cls; end
9
+ def +(str); @element.name + str; end
10
+
11
+ def to_s; (prefix.nil? || prefix == '' ? '' : prefix + ':') + @element.name; end
12
+ def to_sym; to_s.to_sym; end
13
+ def name; @element.name; end
14
+ def name=(n); @element.name = n; end
15
+
16
+ def prefix
17
+ if @element.namespace
18
+ if @element.namespace.prefix.nil?
19
+ ''
20
+ else
21
+ @element.namespace.prefix
22
+ end
23
+ else
24
+ nil
25
+ end
26
+ end
27
+
28
+ def href
29
+ @element.namespace ? @element.namespace.href : nil
30
+ end
31
+ end
32
+
33
+ end
34
+ end
data/test/1.xml ADDED
@@ -0,0 +1 @@
1
+ <me/>
data/test/2.xml ADDED
@@ -0,0 +1 @@
1
+ <me/>
data/test/3.xml ADDED
@@ -0,0 +1 @@
1
+ <me/>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="ISO-8859-1"?>
2
+ <test xmlns='http://example.org' xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/">
3
+ <names>
4
+ <name team="0" a="3">Renate</name>
5
+ <name team="1">J�rgen</name>
6
+ <name team="1">Michel</name>
7
+ <name team="1">Raphi</name>
8
+ <name team="2">Kathrin <b>Fiedler</b></name>
9
+ <name team="2">Egon</name>
10
+ <test_node>a<b/>c<!-- argh --><![CDATA[ deity ]]></test_node>
11
+ </names>
12
+ <colors xmlns='http://example1.org'>
13
+ <blue taint="true">Yeah</blue>
14
+ <red taint="true"></red>
15
+ <green taint="true"/>
16
+ </colors>
17
+ <soap:hallo/>
18
+ </test>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0" encoding="ISO-8859-1"?>
2
+ <test xml:lang='de' xmlns:test='http://xxx.org' xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns='http://default.org'>
3
+ <names>
4
+ <name team="0" a="3">Renate</name>
5
+ <name team="1">J�rgen</name>
6
+ <name team="1">Michel</name>
7
+ <name team="1">Raphi</name>
8
+ <name team="2">Kathrin <b>Fiedler</b></name>
9
+ <name team="2">Egon</name>
10
+ <test_node>a<b/>c<!-- argh --><![CDATA[ deity ]]></test_node>
11
+ </names>
12
+ <colors>
13
+ <blue taint="true">Yeah</blue>
14
+ <red taint="true"></red>
15
+ <green taint="true"/>
16
+ </colors>
17
+ <soap:hallo/>
18
+ </test>
@@ -0,0 +1,6 @@
1
+ <contributors>
2
+ <guy id="1" nick="eTM">Jürgen</guy>
3
+ <guy id="2" nick="chris2">Christian</guy>
4
+ <guy id="3">Emanuel</guy>
5
+ <guy id="4">41</guy>
6
+ </contributors>
@@ -0,0 +1,6 @@
1
+ <contributors>
2
+ <guy id="1" nick="eTM">Jürgen</guy>
3
+ <guy id="2" nick="chris2">Christian</guy>
4
+ <guy id="3">Emanuel</guy>
5
+ <guy id="4">41</guy>
6
+ </contributors>
@@ -0,0 +1,4 @@
1
+ <elements>
2
+ <element>Thread 1</element>
3
+ <element>Thread 2</element>
4
+ </elements>
@@ -0,0 +1,4 @@
1
+ <elements>
2
+ <element>Thread 1</element>
3
+ <element>Thread 2</element>
4
+ </elements>
data/test/EXAMPLE.xml ADDED
@@ -0,0 +1,17 @@
1
+ <test xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xml:lang="de">
2
+ <names>
3
+ <name team="0" a="3">2012-10-18 01:00:26 +0200</name>
4
+ <name team="1">Jürgen</name>
5
+ <name team="1">Michel</name>
6
+ <name team="1">Raphi</name>
7
+ <name team="2">Kathrin <b>Fiedler</b></name>
8
+ <name team="2">Egon</name>
9
+ <test_node>a<b/>c<!-- argh --><![CDATA[ deity ]]></test_node>
10
+ </names>
11
+ <colors>
12
+ <blue taint="true">Yeah</blue>
13
+ <red taint="true"/>
14
+ <green taint="true"/>
15
+ </colors>
16
+ <soap:hallo/>
17
+ </test>
@@ -0,0 +1 @@
1
+ <hello>hello curucamp</hello>
data/test/HELLO.rng ADDED
@@ -0,0 +1,9 @@
1
+ <element name="hellos" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes" xmlns="http://relaxng.org/ns/structure/1.0">
2
+ <oneOrMore>
3
+ <element name="hello">
4
+ <data type="string">
5
+ <param name="pattern">hello .+</param>
6
+ </data>
7
+ </element>
8
+ </oneOrMore>
9
+ </element>
data/test/HELLO.xml ADDED
@@ -0,0 +1,8 @@
1
+ <hellos xmlns:xi="http://www.w3.org/2001/XInclude">
2
+ <hello>hello world</hello>
3
+ <hello>hello obama</hello>
4
+ <hello>hello china</hello>
5
+ <hello>hello austria</hello>
6
+ <hello>hello me</hello>
7
+ <xi:include href="HELLO-MORE.xml"/>
8
+ </hellos>
data/test/HELLO.xsd ADDED
@@ -0,0 +1,16 @@
1
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xi="http://www.w3.org/2001/XInclude">
2
+ <xsd:simpleType name="hellopattern">
3
+ <xsd:restriction base="xsd:string">
4
+ <xsd:pattern value="hello .+"/>
5
+ </xsd:restriction>
6
+ </xsd:simpleType>
7
+
8
+ <xsd:element name="hellos">
9
+ <xsd:complexType>
10
+ <xsd:sequence>
11
+ <xsd:element name="hello" type="hellopattern" minOccurs="1" maxOccurs="unbounded"/>
12
+ </xsd:sequence>
13
+ </xsd:complexType>
14
+ </xsd:element>
15
+
16
+ </xsd:schema>
data/test/XSL_BASE.xml ADDED
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0"?>
2
+ <doc>
3
+ <title>Document Title</title>
4
+ <chapter>
5
+ <title>Chapter Title</title>
6
+ <section>
7
+ <title>Section Title</title>
8
+ <para>This is a test.</para>
9
+ <note>This is a note.</note>
10
+ </section>
11
+ <section>
12
+ <title>Another Section Title</title>
13
+ <para>This is <emph>another</emph> test.</para>
14
+ <note>This is another note.</note>
15
+ </section>
16
+ </chapter>
17
+ </doc>
@@ -0,0 +1,16 @@
1
+ <doc>
2
+ <title>Document Title</title>
3
+ <chapter>
4
+ <title>Chapter Title</title>
5
+ <section>
6
+ <title>Section Title</title>
7
+ <para>This is a test.</para>
8
+ <note>This is a note.</note>
9
+ </section>
10
+ <section>
11
+ <title>Another Section Title</title>
12
+ <para>This is <emph>another</emph> test.</para>
13
+ <note>This is another note.</note>
14
+ </section>
15
+ </chapter>
16
+ </doc>
@@ -0,0 +1,48 @@
1
+ <?xml version="1.0"?>
2
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/TR/xhtml1/strict" version="1.0">
3
+ <xsl:strip-space elements="doc chapter section"/>
4
+ <xsl:output method="xml" indent="yes" encoding="iso-8859-1"/>
5
+ <xsl:template match="doc">
6
+ <html>
7
+ <head>
8
+ <title>
9
+ <xsl:value-of select="title"/>
10
+ </title>
11
+ </head>
12
+ <body>
13
+ <xsl:apply-templates/>
14
+ </body>
15
+ </html>
16
+ </xsl:template>
17
+ <xsl:template match="doc/title">
18
+ <h1>
19
+ <xsl:apply-templates/>
20
+ </h1>
21
+ </xsl:template>
22
+ <xsl:template match="chapter/title">
23
+ <h2>
24
+ <xsl:apply-templates/>
25
+ </h2>
26
+ </xsl:template>
27
+ <xsl:template match="section/title">
28
+ <h3>
29
+ <xsl:apply-templates/>
30
+ </h3>
31
+ </xsl:template>
32
+ <xsl:template match="para">
33
+ <p>
34
+ <xsl:apply-templates/>
35
+ </p>
36
+ </xsl:template>
37
+ <xsl:template match="note">
38
+ <p class="note">
39
+ <b>NOTE: </b>
40
+ <xsl:apply-templates/>
41
+ </p>
42
+ </xsl:template>
43
+ <xsl:template match="emph">
44
+ <em>
45
+ <xsl:apply-templates/>
46
+ </em>
47
+ </xsl:template>
48
+ </xsl:stylesheet>
@@ -0,0 +1 @@
1
+ <solutions><solution matnr="9906264" name="mangler" secid="1" assessment="16"><question block="1" question="2"/><question block="2" question="4"/><question block="3" question="6"/></solution></solutions>
@@ -0,0 +1,25 @@
1
+ $timings = []
2
+
3
+ def start_timing(name)
4
+ $timings << [name,false,Time.now.to_f]
5
+ end
6
+
7
+ def end_timing
8
+ $timings.last[1] = true
9
+ $timings.last[2] = Time.now.to_f - $timings.last[2]
10
+ end
11
+
12
+ class MiniTest::Unit
13
+ OLD_run_anything = instance_method(:_run_anything)
14
+
15
+ def _run_anything type
16
+ OLD_run_anything.bind(self).call(type)
17
+ if $timings.length > 0
18
+ puts
19
+ puts "PERFORMANCE:"
20
+ $timings.each do |tim|
21
+ puts " * #{tim[0]}: #{'%f' % tim[2]} seconds" if tim[1]
22
+ end
23
+ end
24
+ end
25
+ end
data/test/tc_add.rb ADDED
@@ -0,0 +1,21 @@
1
+ require 'rubygems'
2
+ require 'minitest/autorun'
3
+ require File.expand_path(::File.dirname(__FILE__) + '/../lib/xml/smart')
4
+ require File.expand_path(::File.dirname(__FILE__) + '/smartrunner.rb')
5
+
6
+ class TestAdd < MiniTest::Unit::TestCase
7
+ def test_add
8
+ nums = 50000
9
+
10
+ # Watch the power
11
+ start_timing "Replace (#{nums} times)"
12
+ doc = XML::Smart.open(::File.dirname(__FILE__) + "/EXAMPLE.xml")
13
+ 0.upto(nums) { |i|
14
+ nodes = doc.find("/test/names/name[6]")
15
+ nodes.first.parent.add("name", { "team" => "2" }, "Egon")
16
+ }
17
+ end_timing
18
+
19
+ assert(doc.find("/test/names/name").length == nums + 7)
20
+ end
21
+ end
data/test/tc_basic.rb ADDED
@@ -0,0 +1,108 @@
1
+ require 'rubygems'
2
+ require 'minitest/autorun'
3
+ require File.expand_path(::File.dirname(__FILE__) + '/../lib/xml/smart')
4
+ require File.expand_path(::File.dirname(__FILE__) + '/smartrunner.rb')
5
+
6
+ class TestBasic < MiniTest::Unit::TestCase
7
+ def test_criss_cross
8
+ doc = XML::Smart.open(::File.dirname(__FILE__) + "/EXAMPLE.xml")
9
+ node = doc.root.find("/test/names").first
10
+
11
+ assert(node.add("test_node", {"attr" => 12}, "Test1") === XML::Smart::Dom::Element)
12
+ assert(node.add("test_node", "Test2", {"attr" => 13}) === XML::Smart::Dom::Element)
13
+ assert(node.add("test_node", {"attr" => 14, :second => 'a'}) === XML::Smart::Dom::Element)
14
+ assert(node.add("test_node", "Test4") === XML::Smart::Dom::Element)
15
+ assert(node.add("test_node") === XML::Smart::Dom::Element)
16
+ assert(node.add("test_node",'5') === XML::Smart::Dom::Element)
17
+ assert(node.add("test_node",6) === XML::Smart::Dom::Element)
18
+ assert(node.add("test_node",0) === XML::Smart::Dom::Element)
19
+
20
+ assert(doc.find("number(/test/names/test_node[2])").nan?)
21
+ assert(doc.find("number(/test/names/test_node[7])") == 5)
22
+ assert(doc.find("number(/test/names/test_node[8])") == 6)
23
+ assert(doc.find("number(/test/names/test_node[2]/@attr)") == 12)
24
+
25
+ assert(doc.find("string(/test/names/test_node[1])") == "ac deity ")
26
+ assert(doc.find("string(/test/names/test_node[2])") == "Test1")
27
+ assert(doc.find("string(/test/names/test_node[3])") == "Test2")
28
+ assert(doc.find("string(/test/names/test_node[4])") == "")
29
+ assert(doc.find("string(/test/names/test_node[5])") == "Test4")
30
+ assert(doc.find("string(/test/names/test_node[6])") == "")
31
+ assert(doc.find("string(/test/names/test_node[7])") == "5")
32
+ assert(doc.find("string(/test/names/test_node[8])") == "6")
33
+
34
+ assert(doc.find("/test/names/test_node").first.dump == "<test_node>a<b/>c<!-- argh --><![CDATA[ deity ]]></test_node>")
35
+ assert(doc.find("/test/names/test_node").last.dump == "<test_node>0</test_node>")
36
+ assert(doc.find("/test/names/test_node")[0].dump == "<test_node>a<b/>c<!-- argh --><![CDATA[ deity ]]></test_node>")
37
+ assert(doc.find("/test/names/test_node")[1].dump == "<test_node attr=\"12\">Test1</test_node>")
38
+ assert(doc.find("/test/names/test_node")[2].dump == "<test_node attr=\"13\">Test2</test_node>")
39
+ assert(doc.find("/test/names/test_node")[4].dump == "<test_node>Test4</test_node>")
40
+ assert(doc.find("/test/names/test_node")[5].dump == "<test_node/>")
41
+ assert(doc.find("/test/names/test_node")[6].dump == "<test_node>5</test_node>")
42
+ assert(doc.find("/test/names/test_node")[7].dump == "<test_node>6</test_node>")
43
+ assert(doc.find("/test/names/test_node")[0..1].last.dump == "<test_node attr=\"12\">Test1</test_node>")
44
+ assert(doc.find("/test/names/test_node")[0,2].last.dump == "<test_node attr=\"12\">Test1</test_node>")
45
+ assert(doc.find("/test/names/test_node")[-1].dump == "<test_node>0</test_node>")
46
+
47
+ tmp = doc.find("/test/names/test_node")[3].dump
48
+ assert(tmp == "<test_node second=\"a\" attr=\"14\"/>" || tmp == "<test_node attr=\"14\" second=\"a\"/>")
49
+
50
+ nodes = doc.find("/test/names/test_node")
51
+ assert(nodes.length == 9)
52
+ assert(nodes.empty? == false)
53
+ assert(nodes.delete_all! == true)
54
+ assert(nodes.length == 0)
55
+ assert(nodes.empty? == true)
56
+ assert(doc.find("/test/names/test_node").length == 0)
57
+ assert(doc.find("/test/names/test_node").empty? == true)
58
+
59
+ count = 0
60
+ nodes = doc.find("/test/colors/*")
61
+ assert(nodes.length == 3)
62
+ nodes.delete_if do |node|
63
+ count += 1
64
+ count % 2 == 0
65
+ end
66
+ assert(nodes.length == 2)
67
+ assert(doc.find("/test/colors/*")[0].dump == "<blue taint=\"true\">Yeah</blue>")
68
+ assert(doc.find("/test/colors/*")[1].dump == "<green taint=\"true\"/>")
69
+
70
+ node = doc.find("/test/names").first
71
+ assert(node.children[2].to_s == "Michel")
72
+
73
+ assert(doc.root.attributes['lang'] == 'de')
74
+ assert(doc.root.attributes['lang',true] === XML::Smart::Dom::Attribute)
75
+ assert(doc.find("//@xml:lang")[0].value == 'de')
76
+ doc.find("//@xml:lang")[0].value = 'en'
77
+ assert(doc.find("//@xml:lang")[0].value == 'en')
78
+
79
+ assert(doc.namespaces == {"soap"=>"http://schemas.xmlsoap.org/wsdl/soap/"})
80
+ doc.register_namespace 's', 'http://schemas.xmlsoap.org/wsdl/soap/'
81
+ assert(doc.namespaces == {"soap"=>"http://schemas.xmlsoap.org/wsdl/soap/", "s"=>"http://schemas.xmlsoap.org/wsdl/soap/"})
82
+ assert(doc.find("//soap:hallo").length == 1)
83
+ assert(doc.find("//s:hallo").length == 1)
84
+
85
+ doc = XML::Smart.open(::File.dirname(__FILE__) + "/EXAMPLE-NS.xml")
86
+ assert(doc.namespaces == {"xmlns0"=>"http://example.org", "xmlns1"=>"http://example1.org", "soap"=>"http://schemas.xmlsoap.org/wsdl/soap/"})
87
+ assert(doc.find('//xmlns0:names/xmlns0:name')[2].dump == "<name team=\"1\">Michel</name>")
88
+
89
+ doc = XML::Smart.open(::File.dirname(__FILE__) + "/EXAMPLE-NSE.xml")
90
+ node = doc.find("//soap:hallo")[0]
91
+ doc.register_namespace 'x', 'http://xxx.org'
92
+ assert(node.namespace.to_s == "http://schemas.xmlsoap.org/wsdl/soap/")
93
+ assert(node.namespace.prefix == "soap")
94
+ assert(node.namespace.href == "http://schemas.xmlsoap.org/wsdl/soap/")
95
+ assert(node.qname.prefix == "soap")
96
+ assert(node.qname.href == "http://schemas.xmlsoap.org/wsdl/soap/")
97
+
98
+ node.namespace = 'x'
99
+ assert(node.dump == "<test:hallo/>")
100
+ assert(doc.root.namespaces.length == 3)
101
+ node.namespace = 'xmlns'
102
+ assert(node.dump == "<hallo/>");
103
+
104
+ node = doc.find("/xmlns:test")[0]
105
+ assert(node.qname.prefix == "")
106
+ assert(node.qname.href == "http://default.org")
107
+ end
108
+ end
@@ -0,0 +1,73 @@
1
+ require 'rubygems'
2
+ require 'minitest/autorun'
3
+ require 'time'
4
+ require File.expand_path(::File.dirname(__FILE__) + '/../lib/xml/smart')
5
+ require File.expand_path(::File.dirname(__FILE__) + '/smartrunner.rb')
6
+
7
+ class TestConcurrent < MiniTest::Unit::TestCase
8
+ def test_unformated
9
+ # Watch the power
10
+ nums = 100
11
+
12
+ id = 16
13
+ e_matnr = "9906264"
14
+ e_name = "mangler"
15
+ e_secid = 1
16
+ exam = true
17
+
18
+ result = ""
19
+ p = []
20
+ start_timing "Concurrent - unformatted (#{nums} times)"
21
+ 0.upto(nums) do |i|
22
+ p[i] = Thread.new do
23
+ XML::Smart.modify(::File.dirname(__FILE__) + "/concurrent.xml","<solutions/>") do |xml|
24
+ xml.save_unformated = true
25
+ res = xml.find("/solutions/solution[@matnr=\"#{e_matnr}\" or @secid=\"#{e_secid}\"]").delete_all! if exam
26
+ node = xml.root.add("solution",{:matnr => e_matnr, :name => e_name, :secid => e_secid, :assessment => id})
27
+ 1.upto(3) do |qbi|
28
+ qid = qbi*2
29
+ ques = node.add("question", :block => qbi, :question => qid)
30
+ end
31
+
32
+ result = xml.to_s
33
+ end
34
+ end
35
+ end
36
+
37
+ p.each do |t|
38
+ t.join
39
+ end
40
+ end_timing
41
+ end
42
+
43
+ def test_formated
44
+ # Watch the power
45
+ nums = 100
46
+
47
+ id = 16
48
+ e_matnr = "9906264"
49
+ e_name = "mangler"
50
+ e_secid = 1
51
+ exam = true
52
+
53
+ p = []
54
+ start_timing "Concurrent - formatted (#{nums} times)"
55
+ 0.upto(nums) do |i|
56
+ p[i] = Thread.new do
57
+ XML::Smart.modify(::File.dirname(__FILE__) + "/concurrent.xml","<solutions/>") do |xml|
58
+ res = xml.find("/solutions/solution[@matnr=\"#{e_matnr}\" or @secid=\"#{e_secid}\"]").delete_all! if exam
59
+ node = xml.root.add("solution",{:matnr => e_matnr, :name => e_name, :secid => e_secid, :when => Time.now.xmlschema, :assessment => id})
60
+ 1.upto(3) do |qbi|
61
+ qid = qbi*2
62
+ ques = node.add("question", :block => qbi, :question => qid)
63
+ end
64
+ end
65
+ end
66
+ end
67
+
68
+ p.each do |t|
69
+ t.join
70
+ end
71
+ end_timing
72
+ end
73
+ end
data/test/tc_copy.rb ADDED
@@ -0,0 +1,41 @@
1
+ require 'rubygems'
2
+ require 'minitest/autorun'
3
+ require File.expand_path(::File.dirname(__FILE__) + '/../lib/xml/smart')
4
+ require File.expand_path(::File.dirname(__FILE__) + '/smartrunner.rb')
5
+
6
+ class TestCopy < MiniTest::Unit::TestCase
7
+ def test_copy
8
+ # No closure, so changes are temporary
9
+ doc = XML::Smart.open(::File.dirname(__FILE__) + "/EXAMPLE.xml")
10
+ soc = XML::Smart.string("<?xml version='1.0'?><root xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'><node id='1'><text xmlns='http://aaa'>I am a text</text></node><soap:node id='2'/></root>")
11
+
12
+ # copy a node
13
+ nodeA = doc.root.find("/test/names/name[5]").first
14
+ nodeB = soc.root.find("/root/node[@id='1']").first
15
+ nodeS = soc.root.find("/root/*")
16
+
17
+ doc.root.add(nodeA) # move the node (default, XML::Smart::MOVE)
18
+ doc.root.add(nodeB) # copy the foreign node (default, XML::Smart::COPY)
19
+
20
+ # copy the node 3 times
21
+ 3.times { doc.root.add(nodeA,XML::Smart::COPY) }
22
+
23
+ # copy all elements in nodeset
24
+ doc.root.add(nodeS)
25
+
26
+ assert(doc.find("/test/names/name[2]").first.dump == "<name team=\"1\">J&#xFC;rgen</name>")
27
+ assert(doc.find("/test/names/name[3]").first.dump == "<name team=\"1\">Michel</name>")
28
+ assert(doc.find("/test/names/name[4]").first.dump == "<name team=\"1\">Raphi</name>")
29
+ assert(doc.find("/test/names/name[5]").first.dump == "<name team=\"2\">Egon</name>")
30
+
31
+ assert(doc.find("/test/*[4]").first.dump == "<name team=\"2\">Kathrin <b>Fiedler</b></name>")
32
+ assert(doc.find("/test/*[5]").first.dump == "<node id=\"1\">\n <text xmlns=\"http://aaa\">I am a text</text>\n</node>")
33
+ assert(doc.find("/test/*[6]").first.dump == "<name team=\"2\">Kathrin <b>Fiedler</b></name>")
34
+ assert(doc.find("/test/*[7]").first.dump == "<name team=\"2\">Kathrin <b>Fiedler</b></name>")
35
+ assert(doc.find("/test/*[8]").first.dump == "<name team=\"2\">Kathrin <b>Fiedler</b></name>")
36
+ assert(doc.find("/test/*[9]").first.dump == "<node id=\"1\">\n <text xmlns=\"http://aaa\">I am a text</text>\n</node>")
37
+ assert(doc.find("/test/*[10]").first.dump == "<soap:node id=\"2\"/>")
38
+
39
+ assert(soc.root.dump == "<root xmlns:soap=\"http://schemas.xmlsoap.org/wsdl/soap/\">\n <node id=\"1\">\n <text xmlns=\"http://aaa\">I am a text</text>\n </node>\n <soap:node id=\"2\"/>\n</root>")
40
+ end
41
+ end
data/test/tc_create.rb ADDED
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'minitest/autorun'
3
+ require File.expand_path(::File.dirname(__FILE__) + '/../lib/xml/smart')
4
+ require File.expand_path(::File.dirname(__FILE__) + '/smartrunner.rb')
5
+
6
+ class TestCreate < MiniTest::Unit::TestCase
7
+ def test_create
8
+ # When a string as second paramter is provided, then a empty
9
+ # xml file is created if it not exists. A block has to be supplied
10
+ #
11
+ # XML::Smart.modify(FILE,STRING) {} ... create file if !exists?
12
+ # XML::Smart.modify(FILE) {} ... just open file change and write back (LOCKTIMEOUT defaults to 7)
13
+
14
+ File.unlink ::File.dirname(__FILE__) + "/EXAMPLE.tmp.xml" rescue nil
15
+ t1 = Thread.new do
16
+ XML::Smart.modify(::File.dirname(__FILE__) + "/EXAMPLE.tmp.xml","<elements/>") { |doc|
17
+ node = doc.root.add("element","Thread 1")
18
+ }
19
+ sleep 1
20
+ end
21
+ t2 = Thread.new do
22
+ Thread.pass
23
+ XML::Smart.modify(::File.dirname(__FILE__) + "/EXAMPLE.tmp.xml","<elements/>") { |doc|
24
+ node = doc.root.add("element","Thread 2")
25
+ }
26
+ end
27
+ t1.join
28
+ t2.join
29
+
30
+ assert(XML::Smart.open(::File.dirname(__FILE__) + "/EXAMPLE.tmp.xml").root.to_s == XML::Smart.open(::File.dirname(__FILE__) + "/EXAMPLE.tmp.xml.test").root.to_s)
31
+ end
32
+ end
data/test/tc_delete.rb ADDED
@@ -0,0 +1,52 @@
1
+ # coding: utf-8
2
+ require 'rubygems'
3
+ require 'minitest/autorun'
4
+ require File.expand_path(::File.dirname(__FILE__) + '/../lib/xml/smart')
5
+ require File.expand_path(::File.dirname(__FILE__) + '/smartrunner.rb')
6
+
7
+ class TestDelete < MiniTest::Unit::TestCase
8
+ def test_delete
9
+ doc = XML::Smart.open(::File.dirname(__FILE__) + "/EXAMPLE.xml")
10
+
11
+ nodes = doc.root.find("/test/names/name")
12
+ assert(nodes.length == 6)
13
+
14
+ nodes.delete_if{ |n| n.text == "Egon"; }
15
+ assert(nodes.length == 5)
16
+
17
+ nodes.delete_at(2)
18
+ assert(nodes.length == 4)
19
+
20
+ nodes.delete_at(-2)
21
+ assert(nodes.length == 3)
22
+
23
+ nodes = doc.root.find("/test/names/*")
24
+ assert(nodes[0].qname.name == 'name')
25
+ assert(nodes[0].attributes['team'] == '0')
26
+ assert(nodes[0].attributes['a'] == '3')
27
+
28
+ assert(nodes[1].qname.name == 'name')
29
+ assert(nodes[1].attributes['team'] == '1')
30
+ assert(nodes[1].text == "Jürgen")
31
+
32
+ assert(nodes[2].qname.name == 'name')
33
+ assert(nodes[2].attributes['team'] == '2')
34
+ assert(nodes[2].text == 'Kathrin ')
35
+
36
+ nodes = doc.root.find("/test/names/name/@team")
37
+ nodes.delete_if{ |n| n.to_i % 2 != 0 }
38
+ assert(nodes[0].value == '0')
39
+ assert(nodes[1].value == '2')
40
+ assert(nodes[2].nil?)
41
+
42
+ nodes = doc.root.find("/test/names/name/@team")
43
+ assert(nodes[0].value == '0')
44
+ assert(nodes[1].value == '2')
45
+
46
+ nodes.delete_all!
47
+ assert(nodes.empty?)
48
+
49
+ nodes = doc.root.find("/test/names/name/@team")
50
+ assert(nodes.empty?)
51
+ end
52
+ end
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ require 'rubygems'
3
+ require 'minitest/autorun'
4
+ require File.expand_path(::File.dirname(__FILE__) + '/../lib/xml/smart')
5
+ require File.expand_path(::File.dirname(__FILE__) + '/smartrunner.rb')
6
+
7
+ class TestMoveElements < MiniTest::Unit::TestCase
8
+ def test_move_elements
9
+ doc = XML::Smart.open(::File.dirname(__FILE__) + "/EXAMPLE.xml")
10
+ node = doc.find("/test/names/name[@team='1']").first
11
+
12
+ # add all elements that have a bigger team number as previous siblings
13
+ # (Egon an Kathrin are now before Juergen in the document)
14
+ node.add_before(doc.find("/test/names/name[@team>=2]"))
15
+
16
+ nodes = doc.find("/test/names/name[@team>0]")
17
+ assert(nodes[0].text == "Kathrin ")
18
+ assert(nodes[1].text == "Egon")
19
+ assert(nodes[2].text == "Jürgen")
20
+ assert(nodes[3].text == "Michel")
21
+ assert(nodes[4].text == "Raphi")
22
+ assert(nodes[5].nil?)
23
+ end
24
+ end