Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xpath how do I get the total string length of all attributes on the parent's children?

Tags:

xml

xslt

xpath

A fairly staright foward question, or so I thought...

select="../Store" returns a nodeset containing all of the nodes I need. I then need to calculate the string length of the name attribute attached to the Store node.

I would have thought it would be this: select="string-length(../Store/@name)" but this only returns the string length of the first node.

Any ideas?

like image 621
James Law Avatar asked Feb 28 '12 13:02

James Law


2 Answers

In XPath 2.0 use a single expression like this:

sum(../Store/@name/string-length(.))

This cannot be done with a single XPath 1.0 expression (a function as a location step isn't allowed), therefore some help of the hosting language is needed.

For example, if the hosting language is XSLT:

<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="Store[@name][1]"/>
 </xsl:template>

 <xsl:template match="Store[@name]">
  <xsl:param name="vAccum" select="0"/>

  <xsl:value-of select="$vAccum + string-length(@name)"/>
 </xsl:template>

 <xsl:template match="Store[@name and following-sibling::Store/@name]">
  <xsl:param name="vAccum" select="0"/>

  <xsl:apply-templates select="following-sibling::Store[@name][1]">
    <xsl:with-param name="vAccum" select="$vAccum + string-length(@name)"/>
  </xsl:apply-templates>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the following XML document:

<root>
  <Store name="ab"/>
  <Store name="cde"/>
  <Store name="fgh"/>
  <Store name="ijklmn"/>
  <Store name="opr"/>
</root>

the wanted, correct result is produced:

17

like image 70
Dimitre Novatchev Avatar answered Sep 28 '22 08:09

Dimitre Novatchev


<xsl:variable name="StoreNames">
  <xsl:for-each select="../Store">
    <xsl:value-of select="@name"/>
  </xsl:for-each>
</xsl:variable>

<xsl:value-of select="string-length($StoreNames)" />

Nice and easy!

like image 45
James Law Avatar answered Sep 28 '22 08:09

James Law