How to count all the return value from a loop in xslt?

1,728 views
Skip to first unread message

Rahul H

unread,
Oct 30, 2017, 12:41:06 PM10/30/17
to DITA-OT Users

Hi Developers,


I am working on a DITA OT Validator plugin. I have an issue with count of all return values.

I have 5 xml files, I am trying to get the occurrence of particular word in a particular tag content in each xml


Example:

in all xml files I have a tag like below

<test name="city">City:asdasd,City:asdasd</test>

if the occurrence of City is more than 1 it should return 1


so if all the <test> tags in all xml files returned 1 each, then the result should be5. how can I do this in xslt.

<xsl:variable name="instance">
    <xsl:for-each select="$topiclist//a">
    <xsl:for-each select="document(concat($Path, substring-before(.,'xml'),'met'))//test[@name='city']">
    <xsl:if test="string-length(tokenize(., 'City')) > 0">1
    </xsl:if>
    </xsl:for-each>
    </xsl:for-each>
</xsl:variable>
total instance: <xsl:value-of select="$instance""/>


$topiclist//a is the list of xml files


Some can help me a solution for this or any other better IDea to suggest?

Toshihiko Makita

unread,
Nov 1, 2017, 8:30:48 AM11/1/17
to DITA-OT Users
Hi Rahul,

There is no needs to use xsl:for-each instruction. I've tested using following code and it works as far as in my environment.

[Stylesheet]

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    exclude-result-prefixes="xs"
    version="2.0">
    
    <xsl:param name="prmInputXml" as="xs:string*" select="('a.xml','b.xml','c.xml','d.xml','e.xml','f.xml','g.xml')"/>
    <xsl:variable name="prmInputMetFile" as="xs:string*" select="for $n in 1 to count($prmInputXml) return concat(substring-before($prmInputXml[$n],'.xml'),'.met')"/>
    <xsl:variable name="metFileCollection" as="document-node()*" select="for $m in $prmInputMetFile return document($m)"/>
    <xsl:variable name="cityCount" as="xs:integer*" select="for $d in $metFileCollection return $d//test[string(@name) eq 'city']/(if (count(tokenize(string(.),':|,')[. eq 'City']) gt 1) then 1 else 0)"/>
    <xsl:template match="/">
        <xsl:message select="'Double city file count=',sum($cityCount)"/>
    </xsl:template>
</xsl:stylesheet>

[Test data]

a.met ... e.met

<?xml version="1.0" encoding="UTF-8"?>
<tests>
    <test name="city">City:asdasd,City:asdasd</test>
</tests>

f.met, g.met

<?xml version="1.0" encoding="UTF-8"?>
<tests>
    <test name="city">City:asdasd</test>
</tests>

[The stylesheet outputs]

Double city file count= 5

Hope this helps your development.

Regards,

-- 
/*--------------------------------------------------
 Toshihiko Makita
 Development Group. Antenna House, Inc. Ina Branch
 Web site:
 http://www.antenna.co.jp/
 http://www.antennahouse.com/
 --------------------------------------------------*/ 

Rahul H

unread,
Nov 8, 2017, 3:45:40 AM11/8/17
to DITA-OT Users
Hi Thank you for the help

In my case, DITA OT is generating a temp file fullditatopic.list with all xml file names , how can I pass this xml file names  in  the parameter "prmInputXml"?

Toshihiko Makita

unread,
Nov 8, 2017, 7:25:23 AM11/8/17
to DITA-OT Users
HI,

Probably following sample program will help you.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    exclude-result-prefixes="xs"
    version="2.0">
    
    <xsl:param name="prmTopicListFile" as="xs:string" select="'file:/D:/SVN/pdf5/testdata/index-data-ml/sample_en/temp/fullditatopic.list'"/>
    
    <xsl:template match="/">
        <xsl:variable name="prmInputXml" as="xs:string*">
            <xsl:for-each select="tokenize(unparsed-text($prmTopicListFile),'\n')">
                <xsl:sequence select="."/>
            </xsl:for-each>
        </xsl:variable>
        <xsl:message select="'$prmInputXml=',$prmInputXml"/>
    </xsl:template>

</xsl:stylesheet>

Reply all
Reply to author
Forward
0 new messages