新手 Perl 程序员,试图将简单的 xml 字符串转换为制表符分隔的文本文件。我在使用 XML::Parser(和 XML::Twig/Simple 甚至 XSLT)时遇到了困难,但我不知道如何让主要数据部分成为列标题。
然后我开始尝试用 XSLT 来做,但我不知道如何在元素之间获取分隔符——(然后我会使用 split 和/或 join?)但它们都只是在一个字符串中一起运行。
我只是手动手动打印列标题。有没有一种简单的方法可以用模板做到这一点?
我查看了类似的问题,但看不到任何分隔符被添加到我的文件中。XML 到制表符分隔的文本 修改 XSLT 以将 XML 转换为制表符分隔的文本文件
问题:
一般来说,最简单的方法是什么,我什至应该使用 XSLT(我一直在努力理解)。
我该如何解决以下问题?
看起来我已经很接近了,但只需要在 XSLT 输出字符串中添加一个分隔符,这样我就可以将它拆分,然后在我的输出中将它与“\t”连接到制表符分隔的文本文件中。??
这是我的 XML(来自 Twilio 的 SMS 日志):
<?xml version="1.0" encoding="UTF-8"?>
<TwilioResponse>
<SMSMessages end="49" firstpageuri="/2010-04-01/Accounts/ACcbaa0/SMS/Messages?Page=0&PageSize=50" lastpageuri="/2010-04-01/Accounts/ACcbaa/SMS/Messages?Page=54&PageSize=50" nextpageuri="/2010-04-01/Accounts/ACcbaa0103c/SMS/Messages?Page=1&PageSize=50&AfterSid=SMc20cf7" numpages="55" page="0" pagesize="50" previouspageuri="" start="0" total="2703" uri="/2010-04-01/Accounts/ACcbaa0103cf/SMS/Messages">
<SMSMessage>
<Sid>SMe24eb108b7eb6a3b</Sid>
<DateCreated>Fri, 09 Aug 2013 00:07:59 +0000</DateCreated>
<DateUpdated>Fri, 09 Aug 2013 00:07:59 +0000</DateUpdated>
<DateSent>Fri, 09 Aug 2013 00:07:59 +0000</DateSent>
<AccountSid>ACcbaa0103c4141e5cd754042cb424d4ff</AccountSid>
<To>+14444444444</To>
<From>+15555555555</From>
<Body>Hi there!</Body>
<Status>sent</Status>
<Direction>outbound-api</Direction>
<Price>-0.01000</Price>
<PriceUnit>USD</PriceUnit>
<ApiVersion>2010-04-01</ApiVersion>
<Uri>/2010-04-01/Accounts/ACcbaa01/SMS/Messages/SMe24eb108b</Uri>
</SMSMessage>
<SMSMessage>
... etc. ...
</SMSMessage>
</SMSMessages>
</TwilioResponse>
这是我尝试使用的 XSLT:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:template match="//TwilioResponse">
<xsl:for-each select="SMSMessage">
<xsl:value-of select="Sid"/>
<!-- I tried all these, too:   	 even 
 -->
<xsl:text>	</xsl:text>
<!-- I also tried this from another SO question -->
<xsl:if test="position() != last()">, </xsl:if>
<xsl:value-of select="DateCreated"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="DateUpdated"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="DateSent"/>
<xsl:text>
</xsl:text>
<xsl:value-of select="AccountSid"/>
<xsl:text>	</xsl:text>
<xsl:text>
</xsl:text>
<xsl:text> </xsl:text>
<xsl:text>	</xsl:text>
<xsl:value-of select="To"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="From"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="Body"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="Status"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="Direction"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="Price"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="PriceUnit"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="ApiVersion"/>
<xsl:text>	</xsl:text>
<xsl:value-of select="Uri"/>
<!-- I tried both of these: line feed char -->
<xsl:text>
</xsl:text>
<xsl:text> </xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这是我的 Perl 代码的相关部分:
use XML::XSLT;
my $logs = $twilio -> GET ('SMS/Messages');
my $string = $logs->{content};
my $xsl = 'xsl.txt';
my $xslt = XML::XSLT->new ($xsl);
$xslt->transform ($string);
my $xsltToString = $xslt->toString;
print $xsltToString;
my $columnHeadings = "Sid\tDateCreated\tDateUpdated\tDateSent\tAccountSid\tTo\tFrom\tBody\tStatus\tDirection\tPrice\tPriceUnit\tApiVersion\tUri\n";
open(my $fh, '>', 'textfile.txt') || die("Unable to open file. $!");
print $fh $columnHeadings;
foreach my $k (@split) {
print $fh join("\t", $xsltToString) . "\t";
}
#print $fh split("\t", $val). "\t"; ;
close($fh);
$xslt->dispose();
# P.S. I'm sure there's a better way to check and see how many lines were saved.
my $xmllines = 0;
open $fh, '<', 'textfile.txt' or die "Could not open file. $!";
while (<$fh>) {
$xmllines++;
}
print ("\n" . $xmllines . " lines saved to tab-delimited logs textfile. \n");
close $fh;
我的输出是一回事,任何元素之间都没有分离。