164 lines
4.0 KiB
Ruby
Executable File
164 lines
4.0 KiB
Ruby
Executable File
#
|
|
# Filename:: include.rb
|
|
# Description:: xml include, for projbuild
|
|
#
|
|
# Author:: Greg Smith <greg@rockstarnorth.com>
|
|
#
|
|
#
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Uses
|
|
#-----------------------------------------------------------------------------
|
|
require 'xml'
|
|
|
|
#-----------------------------------------------------------------------------
|
|
# Implementation
|
|
#-----------------------------------------------------------------------------
|
|
|
|
module Pipeline
|
|
module XMLUtil
|
|
|
|
# class LibXML::XML::Node
|
|
# # DW - its far faster to call this since it doesn't iterate over all the attributes as per attributes.length
|
|
# def attributes?
|
|
# attributes.first
|
|
# end
|
|
# end
|
|
|
|
|
|
class Include
|
|
include Singleton
|
|
|
|
def initialize( )
|
|
|
|
schema_filename = "$(toolsconfig)/projbuild/projbuild.xsd"
|
|
|
|
Pipeline::Globals.instance().in_env do |e|
|
|
|
|
schema_filename = e.subst(schema_filename)
|
|
end
|
|
|
|
set_schema(schema_filename)
|
|
end
|
|
|
|
def set_schema( schema_filename )
|
|
|
|
parser = XML::Parser.file(schema_filename)
|
|
@schema = parser.parse
|
|
|
|
@schema_elements = @schema.find( 'xs:element' )
|
|
@schema_elements_all = []
|
|
@schema_elements.each { |schema_node|
|
|
next unless ( schema_node.attributes? )
|
|
@schema_elements_all << schema_node
|
|
}
|
|
end
|
|
|
|
def allow_count( node_name, child_name )
|
|
|
|
@schema_elements_all.each { |schema_node|
|
|
|
|
attributes = schema_node.attributes
|
|
next if ( attributes['name'] != node_name )
|
|
|
|
schema_node_elements = schema_node.find("xs:complexType/xs:sequence/xs:element")
|
|
schema_node_elements.each { |schema_elem|
|
|
|
|
next unless ( schema_elem.attributes? )
|
|
attributes = schema_elem.attributes
|
|
|
|
next if ( attributes['ref'] != child_name )
|
|
return -1 if attributes['maxOccurs'] == "unbounded"
|
|
}
|
|
schema_node_elements = nil
|
|
}
|
|
schema_elements = nil
|
|
|
|
1
|
|
end
|
|
|
|
def merge_node( xml_node, xml_include )
|
|
|
|
if ( xml_include.attributes? ) then
|
|
include_attributes = xml_include.attributes
|
|
target_attributes = xml_node.attributes
|
|
|
|
include_attributes.each do |attribute|
|
|
target_attributes[attribute.name] = attribute.value
|
|
end
|
|
end
|
|
|
|
text_nodes = xml_include.find("text()")
|
|
if ( text_nodes.size > 0 ) then
|
|
text_nodes.each do |text_node|
|
|
|
|
next if ( text_node.content.strip == '' )
|
|
|
|
#xml_node << text_node.copy(false) # this leads to an segmentation fault
|
|
# so copy by hand... for some libxml internals reason this does not lead to a segmentation fault!
|
|
|
|
new_node = nil
|
|
if (text_node.name=="text")
|
|
xml_node.content = text_node.content
|
|
else
|
|
new_node = XML::Node.new(text_node.name)
|
|
text_node.attributes.each { |attr| new_node.attributes = attr }
|
|
new_node.content = text_node.content
|
|
|
|
xml_node << new_node
|
|
end
|
|
end
|
|
end
|
|
text_nodes = nil
|
|
|
|
xml_include.each do |node|
|
|
|
|
next if node.name == "text"
|
|
|
|
allowed = allow_count(xml_node.name,node.name)
|
|
xml_dest = xml_node.find_first(node.name)
|
|
|
|
if allowed == -1 or xml_dest == nil then
|
|
|
|
xml_new = XML::Node.new(node.name)
|
|
|
|
#temporary... makes it easier to read the xml...
|
|
xml_node << ("\n" + " " * (node.path.split("/").size - 1))
|
|
|
|
xml_node << xml_new
|
|
merge_node(xml_new,node)
|
|
else
|
|
|
|
merge_node(xml_dest,node)
|
|
end
|
|
end
|
|
|
|
xml_node
|
|
end
|
|
|
|
def merge_file( xml_node, path )
|
|
|
|
parser = XML::Parser.file(path)
|
|
doc = parser.parse
|
|
|
|
xml_new = doc.root
|
|
|
|
if doc.root["xinclude"] != nil then
|
|
|
|
include_path = doc.root["xinclude"]
|
|
|
|
Pipeline::Globals.instance().in_env do |e|
|
|
|
|
include_path = e.subst(include_path)
|
|
end
|
|
|
|
merge_file(xml_new,include_path)
|
|
end
|
|
|
|
merge_node(xml_node,xml_new)
|
|
end
|
|
end
|
|
|
|
end # XMLUtil module
|
|
end # Pipeline module
|