Question

I wonder whether it is possible to convert this XML

<url name="profile_link">http://example.com/profile/2345/</url>

into this HTML

<a href="http://example.com/profile/2345/">http://example.com/profile/2345/</a>

with the PHP XML Parser.

I do not understand how to fill the href in my link. The URL (i.e. the data content) is accessible via the xml_set_character_data_handler(), but the start handler (exchanging the url with the anchor) was already called before that event is triggered.

Was it helpful?

Solution

Here are two approaches for this:

Replace the nodes using DOM

Replacing nodes requires less bootstrap. It is done completely in PHP.

$xml = <<<'XML'
<url name="profile_link">http://example.com/profile/2345/</url>
XML;

$dom = new DOMDocument();
$dom->loadXml($xml);
$xpath = new DOMXpath($dom);

$nodes = $xpath->evaluate('//url');
foreach ($nodes as $node) {
  $link = $dom->createElement('a');
  $link->appendChild($dom->createTextNode($node->textContent));
  $link->setAttribute('href', $node->textContent);
  $node->parentNode->insertBefore($link, $node);
  $node->parentNode->removeChild($node);
}

var_dump($dom->saveXml($dom->documentElement));

Transform the XML using XSLT

The second approach requires an XSLT template file. XSLT is an language designed to transform XML. So the initial bootstrap is larger, but the actual transformation is easier to define. I would suggest this approach if you need to do other transformations, too.

$xml = <<<'XML'
<url name="profile_link">http://example.com/profile/2345/</url>
XML;

$xsl = <<<'XSL'
<?xml version="1.0"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="url">
  <a href="text()">
    <xsl:value-of select="text()"/>
  </a>
</xsl:template>

<!-- pass through for unknown tags in the xml tree -->
<xsl:template match="*">
  <xsl:element name="{local-name()}">
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="node()"/>
  </xsl:element>
</xsl:template>

</xsl:stylesheet>
XSL;

$dom = new DOMDocument(); 
$dom->loadXml($xml); 

$xslDom =  new DOMDocument();
$xslDom->loadXml($xsl);

$xsltProc = new XsltProcessor();
$xsltProc->importStylesheet($xslDom);

$result = $xsltProc->transformToDoc($dom);

var_dump($result->saveXml($result->documentElement));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top