Module: Moxml::XmlUtils

Included in:
Adapter::Base, Node
Defined in:
lib/moxml/xml_utils.rb,
lib/moxml/xml_utils/encoder.rb

Defined Under Namespace

Classes: Encoder

Instance Method Summary collapse

Instance Method Details

#encode_entities(text, mode = nil) ⇒ Object



10
11
12
# File 'lib/moxml/xml_utils.rb', line 10

def encode_entities(text, mode = nil)
  Encoder.new(text, mode).call
end

#normalize_xml_value(value) ⇒ Object



89
90
91
92
93
94
95
96
# File 'lib/moxml/xml_utils.rb', line 89

def normalize_xml_value(value)
  case value
  when nil then ""
  when true then "true"
  when false then "false"
  else value.to_s
  end
end

#validate_comment_content(text) ⇒ Object

Raises:



37
38
39
40
41
42
43
44
45
# File 'lib/moxml/xml_utils.rb', line 37

def validate_comment_content(text)
  if text.start_with?("-") || text.end_with?("-")
    raise ValidationError, "XML comment cannot start or end with a hyphen"
  end

  return unless text.include?("--")

  raise ValidationError, "XML comment cannot contain double hyphens (--)"
end

#validate_declaration_encoding(encoding) ⇒ Object



20
21
22
23
24
25
26
27
28
# File 'lib/moxml/xml_utils.rb', line 20

def validate_declaration_encoding(encoding)
  return if encoding.nil?

  begin
    Encoding.find(encoding)
  rescue ArgumentError
    raise ValidationError, "Invalid encoding: #{encoding}"
  end
end

#validate_declaration_standalone(standalone) ⇒ Object

Raises:



30
31
32
33
34
35
# File 'lib/moxml/xml_utils.rb', line 30

def validate_declaration_standalone(standalone)
  return if standalone.nil?
  return if ::Moxml::Declaration::ALLOWED_STANDALONE.include?(standalone)

  raise ValidationError, "Invalid standalone value: #{standalone}"
end

#validate_declaration_version(version) ⇒ Object

Raises:



14
15
16
17
18
# File 'lib/moxml/xml_utils.rb', line 14

def validate_declaration_version(version)
  return if ::Moxml::Declaration::ALLOWED_VERSIONS.include?(version)

  raise ValidationError, "Invalid XML version: #{version}"
end

#validate_element_name(name) ⇒ Object

Raises:



47
48
49
50
51
# File 'lib/moxml/xml_utils.rb', line 47

def validate_element_name(name)
  return if name.is_a?(String) && name.match?(/^[a-zA-Z_][\w\-.:]*$/)

  raise ValidationError, "Invalid XML element name: #{name}"
end

#validate_entity_reference_name(name) ⇒ Object

Raises:



98
99
100
101
102
103
104
# File 'lib/moxml/xml_utils.rb', line 98

def validate_entity_reference_name(name)
  # Entity names follow the same pattern as element names
  # They must start with a letter or underscore, followed by letters, digits, hyphens, underscores, periods, or colons
  return if name.is_a?(String) && name.match?(/^[a-zA-Z_][\w\-.:]*$/)

  raise ValidationError, "Invalid entity reference name: #{name}"
end

#validate_pi_target(target) ⇒ Object

Raises:



53
54
55
56
57
58
# File 'lib/moxml/xml_utils.rb', line 53

def validate_pi_target(target)
  return if target.is_a?(String) && target.match?(/^[a-zA-Z_][\w\-.]*$/)

  raise ValidationError,
        "Invalid XML processing instruction target: #{target}"
end

#validate_prefix(prefix) ⇒ Object

Raises:



83
84
85
86
87
# File 'lib/moxml/xml_utils.rb', line 83

def validate_prefix(prefix)
  return if prefix.match?(/\A[a-zA-Z_][\w-]*\z/)

  raise ValidationError, "Invalid namespace prefix: #{prefix}"
end

#validate_uri(uri, mode: :strict) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/moxml/xml_utils.rb', line 60

def validate_uri(uri, mode: :strict)
  # Empty strings are allowed for default namespace undeclaration (xmlns="").
  return if uri.empty?

  # In lenient mode, accept any string as a namespace URI.
  # Only reject strings containing XML-invalid characters (control characters).
  if mode == :lenient
    if uri.match?(/[\x00-\x08\x0B\x0C\x0E-\x1F]/)
      raise ValidationError, "Invalid URI: #{uri}"
    end

    return
  end

  # Namespace names must be valid URI-references per RFC 3986
  # (W3C Namespaces in XML, https://www.w3.org/TR/xml-names/).
  # Use split instead of parse to avoid scheme-specific validation
  # that rejects valid opaque URIs like "mailto:bar".
  URI::RFC3986_PARSER.split(uri)
rescue URI::InvalidURIError
  raise ValidationError, "Invalid URI: #{uri}"
end