4

I have written the following XSLT template:

<xsl:template match="foo:*">
    <xsl:processing-instruction name="php">$s = ob_get_clean(); ob_start(); $this->callExtensionStartHandler('<xsl:value-of select="local-name()" />');</xsl:processing-instruction>
    <xsl:apply-templates/>
    <xsl:processing-instruction name="php">$sExtensionContent = ob_get_clean(); ob_start(); echo $s; echo $this->callExtensionEndHandler('<xsl:value-of select="local-name()" />', $sExtensionContent);</xsl:processing-instruction>
</xsl:template>

Now I want to pass all attributes and their values of the tag to the php function. If I had a template:

<foo:test id="a" bar="xzz"/>

I would like to have an array('id' => 'a', 'bar' => 'xzz') available in my php function. Is that possible. I don't want to restrict the names of the attributes, so there could be any attribute name.

stofl
  • 2,950
  • 6
  • 35
  • 48

2 Answers2

1

Can't you just pass the element itself and then get all the attributes with an appropriate php function? That way you don't need to care about names of the attributes since I am sure there is a way to iterate through all of the attributes of an element in php :)

FailedDev
  • 26,680
  • 9
  • 53
  • 73
  • Great idea, thank you. The disadvantage in my case is that the xml will be transformed once but the result will be included very often and so it would be better to make the transformation only once. (I know this is a very simple transformation that won't cost much). But then also I had the problem of escaping the single quotes. – stofl Oct 08 '11 at 08:04
1

I am not familiar with PHP, but this may be helpful:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:foo="foo:foo">
 <xsl:output method="text"/>

 <xsl:template match="foo:test">
  array(<xsl:apply-templates select="@*"/>)
 </xsl:template>

 <xsl:template match="foo:test/@*">
  <xsl:if test="not(position()=1)">, </xsl:if>
  <xsl:value-of select=
  'concat(&quot;&apos;&quot;,name(),&quot;&apos;&quot;,
          " => ",
          &quot;&apos;&quot;,.,&quot;&apos;&quot;)'/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on this XML document (the provided one, made well-formed):

<foo:test id="a" bar="xzz" xmlns:foo="foo:foo"/>

the wanted, correct result is produced:

  array('id' => 'a', 'bar' => 'xzz')

Update: In a comment the OP asked:

Thank you, that looks great! Is it possible to add an escaping to the attribute value? Every ' should become \'

Answer: Yes, we can get this output by slightly modifying the original solution:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:foo="foo:foo">
 <xsl:output method="text"/>

 <xsl:template match="foo:test">
  array(<xsl:apply-templates select="@*"/>)
 </xsl:template>

 <xsl:template match="foo:test/@*">
  <xsl:if test="not(position()=1)">, </xsl:if>
  <xsl:value-of select=
  'concat(&quot;\&quot;,&quot;&apos;&quot;,name(),&quot;\&quot;,&quot;&apos;&quot;,
          " => ",
          &quot;\&quot;,&quot;&apos;&quot;,.,&quot;\&quot;,&quot;&apos;&quot;)'/>
 </xsl:template>
</xsl:stylesheet>

When applied on the same XML document, this transformation produces:

  array(\'id\' => \'a\', \'bar\' => \'xzz\')
Dimitre Novatchev
  • 240,661
  • 26
  • 293
  • 431
  • Thank you, that looks great! Is it possible to add an escaping to the attribute value? Every ' should become \' – stofl Oct 08 '11 at 07:58
  • @stofl: Yes it is possible -- I have updated my answer (look at the very end) to produce this desired result. – Dimitre Novatchev Oct 08 '11 at 15:51
  • Oh sorry. I should have described more what I mean. What I need is that a tag then the result should be: array('a\'b'). Is that possible? – stofl Oct 10 '11 at 08:05