Ah, I never cleaned up the code and am reaping the rewards now. This post is pretty long, so I've used readmore to explain everything in detail.
Ok, here's basically what's going on. You were mixing single quotes and double quotes while escaping the < and > tags. You do not need to do this. The only way that format will begin replacing these characters (along with |'s) is if they follow either an @ symbol or a ^ symbol. The reason that you're getting a space in front of \quantity> is that the entire line looks something like the following (using your original code of course, this is what is getting evaluated):
1: format LOG = 2: <?xml version="1.0"?> 3: <order> 4: <product>@<<<<<<<\product> 5: $item 6: <quantity>@<<\quantity> 7: $OrderQty 8: <\order> 9: .
Notice on line 4 how you have @<<<<<<<. Format interprets that as a field with a width of 8 characters that is left-justified. Same thing happens on line 6, except this time the field is 3 characters wide. Now with your variables set the way they are, you get output that looks likes this:
<?xml version="1.0"?> <order> <product>heat741a\product> <quantity>55 \quantity> <\order>
Since heat741a is 8 characters long, it fits perfectly. I don't know if you prefered heat741 instead, since that's what it becomes when the code at the end of the post is executed. However, since 55 is 2 characters long and format is saving three spaces for a string, the string is left justified and padded on the right with a space.
Now what about using '\<'? There's a slight difference between using single quotes vs using double quotes. When you use double quotes, any special symbols are interpolated. This means that they are evaluated so you get their meaning. When using single quotes, the only escape sequences that are interpolated are \\(gives \) and \' (gives '). This is why when you want an @ symbol to show up in the format, you must use '@'. Otherwise, you get a blank space. (I'll leave this excercise to you)
Ok, now that we've gone through all of this, how can we put the < where we need it so it doesn't get misinterpreted by format? Well, it's actually pretty simple. format only looks to start replacements when it finds the @ or ^ symbol until a symbol that isn't a <,|, or >. Well, both @ and ^ aren't in that group so we can just replace the < that we want to show up with a @ and add another value to the value list. Thus, our code will look as such:
1: $item="heat741a"; 2: $OrderQty = 55; 3: open(LOG, ">order.xml") || die "Can't open the log file: $!\n"; 4: $format = "format LOG = \n" 5: . "<?xml version=\"1.0\"?>\n" 6: . "<order>\n" 7: . "<product>" . '@<<<<<<@' . "/product>\n" 8: . '$item,"<"' . "\n" 9: . "<quantity>" . '@' . '<' x (length($OrderQty) - 1) . '@' . "/qua +ntity>\n" 10: . '$OrderQty,"<"' . "\n" 11: . "\</order>\n" 12: . ".\n"; 13: eval $format; 14: write LOG; 15: close LOG;
Notice on lines 7 and 8. Both have an extra @ where you'd expect to start the closing tags. Thus each would require format to look for two values on the next line. On lines 8 and 10 that I put a literal "<" as part of the value list. The only symbols that you need to use this trick for are @ and ^ in all cases, and <, |, and > when following @, ^, <, |, or >. Now that we have gone over all these points, allow me to ask you a few questions. First, are you using this code in something such as a loop that would justify using format? If not, allow me to urge you to follow the directions of either bobn or gmpassos as these methods don't requre the use of eval (which is slow).
Sorry for not going into greater detail the first time.
antirice
The first rule of Perl club is - use Perl
The ith rule of Perl club is - follow rule i - 1 for i > 1
In reply to Re: Re: Re: Format weird behaviour
by antirice
in thread Format weird behaviour
by Anonymous Monk
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |