ricksj
September 8, 2010, 3:16pm
1
Given the XML:
<?xml version="1.0" encoding="UTF-8"?>
<reference>
<refbody>
<section>
<p>
<ul>
<li><xref href="file1.dita#anchor" /></li>
<li><xref href="file2.dita#anchor" /></li>
</ul>
</p>
</section>
<section>
<p>
<xref href="file3.dita#anchor" />
</p>
<p>
<xref href="file4.dita#anchor" />
</p>
</section>
</refbody>
</reference>
I would like to get a list of xref href values:
href="file1.dita#anchor"
href="file2.dita#anchor"
href="file3.dita#anchor"
href="file4.dita#anchor"
I've used Perl XML::Simple, but it requires that I know the document structure of the document and since these xrefs can occur anywhere in the document, I'm not sure how to handle this. I have several files to process so any assistance you can provide would be helpful.
STOIE
September 8, 2010, 8:28pm
2
my_perl_script.pl
#!/usr/bin/perl
while (<>) {
chomp $_;
if ($_ =~ /.*xref\ (href\=\"\S+\")\ \/\>.*/) {
print $1 . "\n";
}
}
Then run it something like this:
cat /my/xml_file.xml |my_perl_script.pl
If the regex pattern of interest lies in a single line, then:
$
$
$ cat sample.xml
<?xml version="1.0" encoding="UTF-8"?>
<reference>
<refbody>
<section>
<p>
<ul>
<li><xref href="file1.dita#anchor" /></li>
<li><xref href="file2.dita#anchor" /></li>
</ul>
</p>
</section>
<section>
<p>
<xref href="file3.dita#anchor" />
</p>
<p>
<xref href="file4.dita#anchor" />
</p>
</section>
</refbody>
</reference>
$
$
$ perl -lne '/^.*(href=".*").*$/ && print $1' sample.xml
href="file1.dita#anchor"
href="file2.dita#anchor"
href="file3.dita#anchor"
href="file4.dita#anchor"
$
$
tyler_durden
ricksj
September 9, 2010, 12:56pm
4
Thank you all for your replies. I found an XPath module that does the trick.
#!/usr/bin/perl
use XML::XPath;
use XML::XPath::XMLParser;
@files = <*.dita>;
foreach my $file (@files) {
my $xp = XML::XPath->new(filename => $file);
my $xrefnode = $xp->find('//xref/@href'); # find all xrefs
print "Processing file: ".$file."\n";
foreach my $node ($xrefnode->get_nodelist) {
my $XrefNode = XML::XPath::XMLParser::as_string($node);
print " xref: ". $XrefNode,"\n";
}
}
Here is a XSLT stylesheet which will output what you are looking for
<?xml version="1.0"?>
<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="//xref/@href"/>
</xsl:template>
<xsl:template match="//xref/@href" >
xref: <xsl:value-of select="." />
</xsl:template>
</xsl:stylesheet>