moxml 0.5.79 → 0.5.80
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.
- checksums.yaml +4 -4
- data/lib/moxml/adapter/base.rb +10 -0
- data/lib/moxml/adapter/leptris.rb +25 -0
- data/lib/moxml/element.rb +23 -0
- data/lib/moxml/version.rb +1 -1
- data/spec/moxml/element_add_element_spec.rb +50 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 656e065f07ecc3aea2624682345254907cab3bee557d14a74e7a9a1e6d3e53f2
|
|
4
|
+
data.tar.gz: d3606b240493ed82eb131bb8dd37e7d011bcd4d7d12d8907407c5408fcecb970
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: d956c3ff27cae1eedce7a4cc9cb53f57a7d12a58999b74ddebb7bc4a3c99661e2cea010a5a2cc9682315ed5d4bfe06b4122453127d6682ecb96fcfd4401202e2
|
|
7
|
+
data.tar.gz: 478679f5fc817ba910aa0adc927ca0e22009ec1cc787b1388cef9ed3ff570da51c83eaa5e5a99f9b4b9c21e2d6d0d8dbed280925035bc00b580ba242776e7766
|
data/lib/moxml/adapter/base.rb
CHANGED
|
@@ -358,6 +358,16 @@ namespace_validation_mode: :strict)
|
|
|
358
358
|
nil
|
|
359
359
|
end
|
|
360
360
|
|
|
361
|
+
# Single-crossing construction contract
|
|
362
|
+
# (Moxml::Element#add_element): create + attach under parent
|
|
363
|
+
# + all attributes in one call, returning the new native
|
|
364
|
+
# element. This default has no bulk face — nil sends the
|
|
365
|
+
# caller down the portable create_element + add_child path;
|
|
366
|
+
# adapters with the face override (leptris — #312/#1344).
|
|
367
|
+
def create_element_with_attrs(_parent, _name, _attrs)
|
|
368
|
+
nil
|
|
369
|
+
end
|
|
370
|
+
|
|
361
371
|
# Read-only attribute listing as [name, value] pairs
|
|
362
372
|
# (Moxml::Element#attribute_pairs) — document order,
|
|
363
373
|
# duplicates included, no Attribute node wrappers. The
|
|
@@ -1488,6 +1488,31 @@ module Moxml
|
|
|
1488
1488
|
line.zero? ? nil : line
|
|
1489
1489
|
end
|
|
1490
1490
|
|
|
1491
|
+
# Single-crossing construction (#312/#1344 consumer face):
|
|
1492
|
+
# create + attach under parent + all attributes in ONE
|
|
1493
|
+
# Ruby->C call (create_child is create+attach; the attr
|
|
1494
|
+
# loop is C->C dlsym). Requires parent binding + the face;
|
|
1495
|
+
# callers fall back to create_element + set_attribute +
|
|
1496
|
+
# add_child when absent.
|
|
1497
|
+
def create_element_with_attrs(parent, name, attrs)
|
|
1498
|
+
binding_parent = to_binding(parent)
|
|
1499
|
+
doc = binding_parent.document or return nil
|
|
1500
|
+
return nil unless ::Leptris::XML::Native.respond_to?(:create_element_with_attrs)
|
|
1501
|
+
|
|
1502
|
+
flat = attrs.flatten
|
|
1503
|
+
addr = ::Leptris::XML::Native.create_element_with_attrs(
|
|
1504
|
+
doc.c_address, binding_parent.c_address, name.to_s, flat)
|
|
1505
|
+
return nil if addr.nil? || addr.zero?
|
|
1506
|
+
|
|
1507
|
+
# The binding's own wrap produces the proper binding
|
|
1508
|
+
# Element (kind class, @c_address, @document); canonical
|
|
1509
|
+
# convergence (#219) hands every accessor — children
|
|
1510
|
+
# included — the SAME native, so the wrapper identity
|
|
1511
|
+
# holds across later traversals.
|
|
1512
|
+
canonical_native(doc,
|
|
1513
|
+
::Leptris::XML::Node.wrap(::FFI::Pointer.new(addr), doc))
|
|
1514
|
+
end
|
|
1515
|
+
|
|
1491
1516
|
def attributes(element)
|
|
1492
1517
|
element = to_binding(element)
|
|
1493
1518
|
element.attribute_nodes
|
data/lib/moxml/element.rb
CHANGED
|
@@ -126,6 +126,29 @@ module Moxml
|
|
|
126
126
|
adapter.attribute_pairs(@native)
|
|
127
127
|
end
|
|
128
128
|
|
|
129
|
+
# Create an element with attributes and attach it under this
|
|
130
|
+
# element — ONE construction on adapters with the bulk face
|
|
131
|
+
# (leptris, #312/#1344 consumer face): create + attach + all
|
|
132
|
+
# attributes in a single Ruby->C crossing. Returns the child
|
|
133
|
+
# wrapper. Equivalent to create_element + attribute writes +
|
|
134
|
+
# add_child, minus two crossings and the intermediate churn.
|
|
135
|
+
def add_element(name, attrs = {})
|
|
136
|
+
native_child = adapter.create_element_with_attrs(
|
|
137
|
+
@native, name, attrs
|
|
138
|
+
)
|
|
139
|
+
if native_child
|
|
140
|
+
adapter.node_type(native_child)
|
|
141
|
+
Moxml::Node.wrap_with(native_child, context, adapter)
|
|
142
|
+
else
|
|
143
|
+
fallback = Moxml::Node.wrap_with(
|
|
144
|
+
adapter.create_element(name), context, adapter
|
|
145
|
+
)
|
|
146
|
+
attrs.each { |k, v| fallback[k] = v.to_s }
|
|
147
|
+
add_child(fallback)
|
|
148
|
+
fallback
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
129
152
|
def attributes
|
|
130
153
|
# Primed like Node.wrap: the adapter and type are known at
|
|
131
154
|
# mint, so the first name/value/attribute? access skips the
|
data/lib/moxml/version.rb
CHANGED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "spec_helper"
|
|
4
|
+
|
|
5
|
+
# Element#add_element adapter-contract conformance (#312): the
|
|
6
|
+
# child must land attached with ALL attributes in one call —
|
|
7
|
+
# through the bulk face (leptris) or the portable create_element +
|
|
8
|
+
# add_child fallback (every other adapter). Guards both halves of
|
|
9
|
+
# the contract: a missing base default NoMethodErrors on non-face
|
|
10
|
+
# adapters, a broken fallback loses attributes or the attach.
|
|
11
|
+
RSpec.describe Moxml::Element do
|
|
12
|
+
ADAPTERS = %i[leptris nokogiri ox oga rexml libxml].freeze # rubocop:disable Lint/ConstantDefinitionInBlock, RSpec/LeakyConstantDeclaration
|
|
13
|
+
|
|
14
|
+
def with_adapter(name)
|
|
15
|
+
ctx = Moxml.new(name)
|
|
16
|
+
yield ctx
|
|
17
|
+
rescue StandardError, LoadError
|
|
18
|
+
skip "adapter #{name} unavailable"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "attaches a child with all attributes on every available adapter" do
|
|
22
|
+
ADAPTERS.each do |name|
|
|
23
|
+
with_adapter(name) do |ctx|
|
|
24
|
+
doc = ctx.parse("<catalog/>")
|
|
25
|
+
root = doc.root
|
|
26
|
+
child = root.add_element("record", "id" => "r1", "kind" => "k1")
|
|
27
|
+
|
|
28
|
+
expect(child.name).to eq("record"), "#{name}: name"
|
|
29
|
+
expect(child["id"]).to eq("r1"), "#{name}: id attr"
|
|
30
|
+
expect(child["kind"]).to eq("k1"), "#{name}: kind attr"
|
|
31
|
+
expect(child.parent.name).to eq("catalog"), "#{name}: attach"
|
|
32
|
+
expect(root.children.map(&:name)).to include("record"), "#{name}: visible in children"
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it "nests under a non-root element with empty attrs" do
|
|
38
|
+
ADAPTERS.each do |name|
|
|
39
|
+
with_adapter(name) do |ctx|
|
|
40
|
+
doc = ctx.parse("<catalog><record/></catalog>")
|
|
41
|
+
record = doc.root.children.first
|
|
42
|
+
field = record.add_element("field")
|
|
43
|
+
|
|
44
|
+
expect(field.name).to eq("field"), "#{name}: name"
|
|
45
|
+
expect(field.attributes).to be_empty, "#{name}: no attrs"
|
|
46
|
+
expect(field.parent.name).to eq("record"), "#{name}: attach"
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: moxml
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.5.
|
|
4
|
+
version: 0.5.80
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ribose Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: |
|
|
14
14
|
Moxml is a unified XML manipulation library that provides a common API
|
|
@@ -468,6 +468,7 @@ files:
|
|
|
468
468
|
- spec/moxml/document_free_spec.rb
|
|
469
469
|
- spec/moxml/document_parse_diagnostics_spec.rb
|
|
470
470
|
- spec/moxml/document_spec.rb
|
|
471
|
+
- spec/moxml/element_add_element_spec.rb
|
|
471
472
|
- spec/moxml/element_attribute_pairs_spec.rb
|
|
472
473
|
- spec/moxml/element_spec.rb
|
|
473
474
|
- spec/moxml/entity_preservation_spec.rb
|