как создать генератор древовидной структуры с рубином в файле xml?
Я работаю над проектом, в котором мне нужно создать пакет msi из Ubuntu для Windows.
Мне удалось создать файл msi из Ubuntu rgace в «msitools», который использует файлы wxs (это похоже на файл xml) для настройки пакета.
Пример файла wxs, который занимает один файл (FoobarAppl10.exe).
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product Name='Foobar 1.0' Id='ABCDDCBA-86C7-4D14-AEC0-86416A69ABDE' UpgradeCode='ABCDDCBA-7349-453F-94F6-BCB5110BA4FD'
Language='1033' Codepage='1252' Version='1.0.0' Manufacturer='Acme Ltd.'>
<Package Id='*' Keywords='Installer' Description="Acme's Foobar 1.0 Installer"
Comments='Foobar is a registered trademark of Acme Ltd.' Manufacturer='Acme Ltd.'
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
<Media Id='1' Cabinet='Sample.cab' EmbedCab='yes' DiskPrompt="CD-ROM #1" />
<Property Id='DiskPrompt' Value="Acme's Foobar 1.0 Installation [1]" />
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='Acme' Name='Acme'>
<Directory Id='INSTALLDIR' Name='Foobar 1.0'>
<Component Id='MainExecutable' Guid='ABCDDCBA-83F1-4F22-985B-FDB3C8ABD471'>
<File Id='FoobarEXE' Name='FoobarAppl10.exe' DiskId='1' Source='FoobarAppl10.exe' KeyPath='yes'/>
</Component>
</Directory>
</Directory>
</Directory>
</Directory>
<Feature Id='Complete' Level='1'>
<ComponentRef Id='MainExecutable' />
</Feature>
</Product>
</Wix>
Теперь моя проблема состоит в том, чтобы создать генератор древовидной структуры с рубином, чтобы мой файл wxs упаковывал все файлы моего проекта, не записывая его вручную.
Я пишу код, который может создать файл xml и распечатать мой брут-код:
$ лс
build.wxs foobarAppl10.exe генератор_xml.rb
require 'nokogiri'
out_file = File.new("generated.wxs", "w")
builder = Nokogiri::XML::Builder.new(:encoding => 'windows-1252') { |xml|
xml.Wix('xmlns' => 'http://schemas.microsoft.com/wix/2006/wi') do
xml.Product('Name' => 'Foobar 1.0', 'Id' => 'ABCDDCBA-86C7-4D14-AEC0-86416A69ABDE',
'UpgradeCode' =>'ABCDDCBA-7349-453F-94F6-BCB5110BA4FD', 'Language' => '1033', 'Codepage' => '1252',
'Version' => '1.0.0', 'Manufacturer' => 'Acme Ltd.') do
xml.Package('Id' => '*', 'Keywords' => 'Installer', 'Description' => "Acme's Foobar 1.0 Installer",
'Comments' => 'Foobar is a registered trademark of Acme Ltd.', 'Manufacturer' => 'Acme Ltd.',
'InstallerVersion' => '100', 'Languages' => '1033', 'Compressed' => 'yes', 'SummaryCodepage' => '1252')
xml.Media('Id' => '1', 'Cabinet' => 'Sample.cab', 'EmbedCab' => 'yes', 'DiskPrompt' => "CD-ROM #1")
xml.Property('Id' => 'DiskPromt', 'Value' => "Acme's Foobar 1.0 Installation [1]")
xml.Directory('Id' => 'TARGETDIR', 'Name' =>'SourceDir') do
xml.Directory('Id' => 'ProgramFilesFolder', 'Name' =>'PFiles') do
xml.Directory('Id' => 'Acme', 'Name' =>'Acme') do
xml.Directory('Id' => 'INSTALLDIR', 'Name' =>'Foobar 1.0') do
xml.Component('Id' => 'MainExecutable', 'Guid' => 'ABCDDCBA-83F1-4F22-985B-FDB3C8ABD471') do
xml.File('Id' => 'FoobarEXE', 'Name' => 'FoobarAppl10.exe', 'DiskId' => '1', 'Source' => 'FoobarAppl10.exe', 'KeyPath' =>'yes')
end
end
end
end
end
xml.Feature('Id' => 'Complete', 'Level' => '1') do
xml.Component('Id' => 'MainExecutable')
end
end
end
}
puts builder.to_xml
out_file.puts(builder.to_xml)
out_file.close
Если кто-то знает, как генерировать код из древовидной структуры, это мне очень поможет!
1 ответ
Похоже, вы хотите создать структуру XML, которая имитирует структуру каталогов? Вот рекурсивная функция, которая должна делать большую часть того, что вы хотите, или, по крайней мере, служить хорошей отправной точкой.
require 'nokogiri'
def process_dir(current_path, xml)
return if !File.directory?(current_path) || Dir.empty?(current_path)
directory_name = current_path.split("/").last
# insert code here to compute other attributes for Directory node
xml.Directory(Name: directory_name) do
Dir.children(current_path).each do |entry|
file = "#{current_path}/#{entry}"
if !File.directory?(file)
# insert code here to compute other attributes for File node
xml.File(Name: entry)
puts "found file named #{entry} at #{current_path}"
else
puts "found directory named #{current_path}/#{entry}"
process_dir("#{current_path}/#{entry}", xml)
end
end
end
end
builder = Nokogiri::XML::Builder.new do |xml|
xml.root { process_dir(".", xml) }
end
pp builder.to_xml