如何在 xml 文件中使用 ruby 创建树结构生成器?
how to create a tree structure generator with ruby in a xml file?
我在一个项目中,我必须从 Ubuntu 为 Windows 创建一个 msi 包。
我设法创建了一个从 Ubuntu rgace 到“msitools”的 msi 文件,它使用 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>
现在我的问题是用ruby创建一个树结构生成器,这样我的wxs文件就可以打包我项目的所有文件而无需手动编写。
我写了一个代码,可以创建一个 xml 文件,并在其中打印我的暴力代码:
$ ls
build.wxs foobarAppl10.exe generator_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
如果有人知道如何从树结构生成代码,那将对我有很大帮助!
听起来您想要创建一个模仿目录结构的 XML 结构?这是一个递归函数,它应该可以完成您想要的大部分工作,或者至少可以作为一个很好的起点。 puts
语句可以删除或替换为您在查找目录或文件时需要执行的任何其他操作。
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
我在一个项目中,我必须从 Ubuntu 为 Windows 创建一个 msi 包。
我设法创建了一个从 Ubuntu rgace 到“msitools”的 msi 文件,它使用 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>
现在我的问题是用ruby创建一个树结构生成器,这样我的wxs文件就可以打包我项目的所有文件而无需手动编写。
我写了一个代码,可以创建一个 xml 文件,并在其中打印我的暴力代码:
$ ls
build.wxs foobarAppl10.exe generator_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
如果有人知道如何从树结构生成代码,那将对我有很大帮助!
听起来您想要创建一个模仿目录结构的 XML 结构?这是一个递归函数,它应该可以完成您想要的大部分工作,或者至少可以作为一个很好的起点。 puts
语句可以删除或替换为您在查找目录或文件时需要执行的任何其他操作。
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