ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
I tried doing a find and replace but clearly that would do everything. I need to only do it the Sequence transformation tags. Your expert advice would be appreciated!!!
I tried doing a find and replace but clearly that would do everything. I need to only do it the Sequence transformation tags. Your expert advice would be appreciated!!!
Your XML fragment is incomplete, so it is difficult to do any comprehensive testing, but I can offer this advice: don't try to contrive a Perl parser for your XML data. Use one of the numerous ready-made modules for the purpose. Which one you choose will depend somewhat on the nature of your data and your application. The easiest one to use is, not surprisingly, XML::Simple, which is a SAX style parser. The potential downside to this parser is that the order of sibling XML elements may be lost in the parse, and that it does not provide a method to write the acquired XML data back to a file.
The other two prominent XML parsers for Perl are the expat-based XML::Parser and the xerces-based XML::Xerces. The APIs for these two are distinctly different, and the XML::Xerces module also provides a method for writing your XML data back to a file.
A sample Perl script that uses the XML::Simple module:
Code:
#! /bin/perl -w
#
# LQrammyp_1979.pl
#
# Reads LQrammyp_979.xml by default
#
use strict;
use XML::Simple;
use Data::Dumper;
my $xmlData;
my $xmlReader = XML::Simple->new();
$xmlData = $xmlReader->XMLin();
# print Dumper( %{$xmlData} );
foreach my $xmlKey ( keys %{$xmlData} ){
print "Element: $xmlKey\n" ;
if( $xmlKey eq "TRANSFORMATION" ){
foreach my $transformation ( @{$xmlData->{$xmlKey}} ){
print "DESCR: '$transformation->{DESCRIPTION}'\n";
print "TYPE :'$transformation->{TYPE}'\n";
print "\tXFORM DTYPE:'$transformation->{TRANSFORMFIELD}->{DATATYPE}'\n";
print "\tXFORM PREC :'$transformation->{TRANSFORMFIELD}->{PRECISION}'\n";
if( $transformation->{TYPE} eq "Sequence" ){
$transformation->{TRANSFORMFIELD}->{DATATYPE}="bigint";
}
}
}
}
This code demonstrates reading the XML (sample data modified, to create valid XML file) data, displaying the content, and modifying the relevant parts. You can create a XML file writer by doing somewhat the reverse of the process demonstrated here. It should be noted that, even though your XML data was posted completely un-formatted here, that the data was still parse-able, which is the basis for my argument against trying to write a parseer that assumes anything about the formatting of the input XML data.
--- rod.
EDIT: As I composed my reply, Sergei was posting his response, and I see that he has given principally the same advice.
This is what I meant when I said "the order of sibling XML elements may be lost in the parse". While this is still perfectly valid XML, some applications are sensitive to order, and XML::Simple will not work where this is the case.
This is what I meant when I said "the order of sibling XML elements may be lost in the parse". While this is still perfectly valid XML, some applications are sensitive to order, and XML::Simple will not work where this is the case.
--- rod.
Or, in Perlish English: XML is like Perl hash - by default after manipulation order of (key, value) pairs is not guaranteed.
Not sure what you mean by "after manipulation", but as I understand it, Perl hashes are always unordered. Since XML::Simple stores data in hashes, the order of retrieval, and presumably therefore, the order of writing, is not preserved.
Not sure what you mean by "after manipulation", but as I understand it, Perl hashes are always unordered. Since XML::Simple stores data in hashes, the order of retrieval, and presumably therefore, the order of writing, is not preserved.
--- rod.
If you fill a Perl hash and then just iterate over it not changing/deleting/adding keys and not changing values, the order of keys is the same in each iteration.
If you change in a Perl hash something, you can't guarantee preservation of order.
OTOH, there are modules implementing hashes with constant keys order (IIRC). It probably won't help the OP since most likely the XML parsers don't use such hashes.
This is what I meant when I said "the order of sibling XML elements may be lost in the parse". While this is still perfectly valid XML, some applications are sensitive to order, and XML::Simple will not work where this is the case.
--- rod.
Thanks Rod. I guess my application is sensitive to order. Is there any other XML parsers out there that would do this? Or can we mainpulate XML Simple in anyway to poduce the same result?
#!/usr/bin/env ruby
file=ARGV[0]
require 'rexml/document'
include REXML
s=""
File.open(file) do |doc|
xml = Document.new(doc)
xml.elements.each("ROOT/TRANSFORMATION") do |elem|
if elem.attributes["TYPE"] == "Sequence"
formatter = REXML::Formatters::Default.new
elem.elements["TRANSFORMFIELD"].attributes["DATATYPE"] = "Integer"
formatter.write(xml,s)
end
end
end
print s
#!/usr/bin/env ruby
file=ARGV[0]
require 'rexml/document'
include REXML
s=""
File.open(file) do |doc|
xml = Document.new(doc)
xml.elements.each("ROOT/TRANSFORMATION") do |elem|
if elem.attributes["TYPE"] == "Sequence"
formatter = REXML::Formatters::Default.new
elem.elements["TRANSFORMFIELD"].attributes["DATATYPE"] = "Integer"
formatter.write(xml,s)
end
end
end
print s
Thanks Rod. I guess my application is sensitive to order. Is there any other XML parsers out there that would do this? Or can we mainpulate XML Simple in anyway to poduce the same result?
If you have sufficient knowledge of the required XML data and the way it is organized, you could create your own writer. It would mean extracting the known data from the Perl data structures in the desired order, and writing them back out to the XML file that way.
The order of tag attributes is usually not a factor for XML-using applications, so if it has been shown that your application is sensitive in that way, it would not be surprising if it is also sensitive to other formatting issues, such as contained whitespace. Sounds like your application may have been written in just the manner that I and Sergei cautioned against. Pity.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.