我有一段很长的XML需要解析。我想要删除除除子类代码和城市之外的所有内容。这样我就只剩下下面这个例子了。
示例
测试子类|迈阿密
代码
<?xml version="1.0" standalone="no"?>
<web-export>
<run-date>06/01/2010
<pub-code>TEST
<ad-type>TEST
<cat-code>Real Estate</cat-code>
<class-code>TEST</class-code>
<subclass-code>TEST SUBCLASS</subclass-code>
<placement-description></placement-description>
<position-description>Town House</position-description>
<subclass3-code></subclass3-code>
<subclass4-code></subclass4-code>
<ad-number>0000284708-01</ad-number>
<start-date>05/28/2010</start-date>
<end-date>06/09/2010</end-date>
<line-count>6</line-count>
<run-count>13</run-count>
<customer-type>Private Party</customer-type>
<account-number>100099237</account-number>
<account-name>DOE, JOHN</account-name>
<addr-1>207 CLARENCE STREET</addr-1>
<addr-2> </addr-2>
<city>MIAMI</city>
<state>FL</state>
<postal-code>02910</postal-code>
<country>USA</country>
<phone-number>4014612880</phone-number>
<fax-number></fax-number>
<url-addr> </url-addr>
<email-addr>noemail@ttest.com</email-addr>
<pay-flag>N</pay-flag>
<ad-description>DEANESTATES2BEDS2BATHSAPPLIANCED</ad-description>
<order-source>Import</order-source>
<order-status>Live</order-status>
<payor-acct>100099237</payor-acct>
<agency-flag>N</agency-flag>
<rate-note></rate-note>
<ad-content> MIAMI/Dean Estates: 2
beds, 2 baths. Applianced. Central air. Carpets. Laundry. 2 decks. Pool. Parking. Close to everything.No smoking. No utilities. $1275 mo. 401-578-1501. </ad-content>
</ad-type>
</pub-code>
</run-date>
</web-export> PERL
因此,我想要做的是打开一个已有的文件,读取内容,然后使用正则表达式消除不必要的XML标记。
open(READFILE, "FILENAME");
while(<READFILE>)
{
$_ =~ s/<\?xml version="(.*)" standalone="(.*)"\?>\n.*//g;
$_ =~ s/<subclass-code>//g;
$_ =~ s/<\/subclass-code>\n.*/|/g;
$_ =~ s/(.*)PJ RER Houses /PJ RER Houses/g;
$_ =~ s/\G //g;
$_ =~ s/<city>//g;
$_ =~ s/<\/city>\n.*//g;
$_ =~ s/<(\/?)web-export>(.*)\n.*//g;
$_ =~ s/<(\/?)run-date>(.*)\n.*//g;
$_ =~ s/<(\/?)pub-code>(.*)\n.*//g;
$_ =~ s/<(\/?)ad-type>(.*)\n.*//g;
$_ =~ s/<(\/?)cat-code>(.*)<(\/?)cat-code>\n.*//g;
$_ =~ s/<(\/?)class-code>(.*)<(\/?)class-code>\n.*//g;
$_ =~ s/<(\/?)placement-description>(.*)<(\/?)placement-description>\n.*//g;
$_ =~ s/<(\/?)position-description>(.*)<(\/?)position-description>\n.*//g;
$_ =~ s/<(\/?)subclass3-code>(.*)<(\/?)subclass3-code>\n.*//g;
$_ =~ s/<(\/?)subclass4-code>(.*)<(\/?)subclass4-code>\n.*//g;
$_ =~ s/<(\/?)ad-number>(.*)<(\/?)ad-number>\n.*//g;
$_ =~ s/<(\/?)start-date>(.*)<(\/?)start-date>\n.*//g;
$_ =~ s/<(\/?)end-date>(.*)<(\/?)end-date>\n.*//g;
$_ =~ s/<(\/?)line-count>(.*)<(\/?)line-count>\n.*//g;
$_ =~ s/<(\/?)run-count>(.*)<(\/?)run-count>\n.*//g;
$_ =~ s/<(\/?)customer-type>(.*)<(\/?)customer-type>\n.*//g;
$_ =~ s/<(\/?)account-number>(.*)<(\/?)account-number>\n.*//g;
$_ =~ s/<(\/?)account-name>(.*)<(\/?)account-name>\n.*//g;
$_ =~ s/<(\/?)addr-1>(.*)<(\/?)addr-1>\n.*//g;
$_ =~ s/<(\/?)addr-2>(.*)<(\/?)addr-2>\n.*//g;
$_ =~ s/<(\/?)state>(.*)<(\/?)state>\n.*//g;
$_ =~ s/<(\/?)postal-code>(.*)<(\/?)postal-code>\n.*//g;
$_ =~ s/<(\/?)country>(.*)<(\/?)country>\n.*//g;
$_ =~ s/<(\/?)phone-number>(.*)<(\/?)phone-number>\n.*//g;
$_ =~ s/<(\/?)fax-number>(.*)<(\/?)fax-number>\n.*//g;
$_ =~ s/<(\/?)url-addr>(.*)<(\/?)url-addr>\n.*//g;
$_ =~ s/<(\/?)email-addr>(.*)<(\/?)email-addr>\n.*//g;
$_ =~ s/<(\/?)pay-flag>(.*)<(\/?)pay-flag>\n.*//g;
$_ =~ s/<(\/?)ad-description>(.*)<(\/?)ad-description>\n.*//g;
$_ =~ s/<(\/?)order-source>(.*)<(\/?)order-source>\n.*//g;
$_ =~ s/<(\/?)order-status>(.*)<(\/?)order-status>\n.*//g;
$_ =~ s/<(\/?)payor-acct>(.*)<(\/?)payor-acct>\n.*//g;
$_ =~ s/<(\/?)agency-flag>(.*)<(\/?)agency-flag>\n.*//g;
$_ =~ s/<(\/?)rate-note>(.*)<(\/?)rate-note>\n.*//g;
$_ =~ s/<ad-content>(.*)\n.*//g;
$_ =~ s/\t(.*)\n.*//g;
$_ =~ s/<\/ad-content>(.*)\n.*//g;
}
close( READFILE1 ); 有没有更简单的方法来做这件事?我不想使用任何模块。我知道这可能会让这件事变得更容易,但我正在读取的文件中包含大量数据。
发布于 2010-06-01 22:42:47
这太可怕了(对不起)。即使您有大量数据,正则表达式也不一定更快。
为什么不使用XSLT?
您的样式表基本上如下所示(如果您只有一个subclass-code和city元素):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:template match="/">
<xsl:apply-templates select="//subclass-code|//city" />
</xsl:template>
<xsl:template match="subclass-code">
<xsl:value-of select="." /><xsl:text> | </xsl:text>
</xsl:template>
<xsl:template match="city">
<xsl:value-of select="." /><xsl:text> </xsl:text>
</xsl:template>
</xsl:stylesheet>(更新了代码以使用多个元素。可能不是最佳解决方案;)
发布于 2010-06-02 02:49:02
如果有人已经编写了像XML::Twig这样的高效(而且我敢说是功能丰富的)模块来解析XML,为什么不使用库呢?
use XML::Twig;
die "Usage: give-me-the-elements.pl <xml_file>\n" unless ($ARGV[0]);
my $twig = XML::Twig->new( twig_handlers =>
{ 'subclass-code' => sub { print->text, "|"; },
'city' => sub { print $_->text, "\n"; },
},
pretty_print => 'indented');
$twig->parsefile($ARGV[0]);
$twig->purge;发布于 2010-06-01 22:43:02
如果您需要一种通用的XML解析方法,请不要使用regex。如果你只需要你所说的(除除子类-code和城市之外的所有东西),如果你确定这两个标签里面没有“奇怪”的东西(xml实体,CDATA部分),并且那些标签不会出现在其他CDATA片段中,等等,你可以简单地这样做:
$/ = undef; # slurp mode
open(READFILE, "FILENAME");
$t = <READFILE>;
close READFILE;
$t =~ s#^.*<subclass-code>(.*?)</subclass-code>.*<city>(.*?)</city>.*$#$1 - $2#s;
# in case the tags could appear in distinct order - uncomment the following
# $t =~ s#^.*<city>(.*?)</city>.*<subclass-code>(.*?)</subclass-code>.*$#$2 - $1#s;
print $t;编辑:更强大一点(嗯),遵循海报的要求:
while( $t =~ m#<pub-code>([^<\s]*).*?<subclass-code>(.*?)</subclass-code>.*?<city>(.*?)</city>#sg) {
print "$1 : $2 | $3 \n";
}但是请停在这里,不要再往前走了,这条路通向地狱...
https://stackoverflow.com/questions/2950661
复制相似问题