3

I asked a similar question on another post but I decided to make this new one since this is a different problem. I am using two XML input files using the document() function to access one of them (the external file). I am trying to use the document() function inside the count() function but I don't know why it is not working... This is the XML input document:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <childs>
        <child ID="1" name="John" />
        <child ID="2" name="Marie"/>
        <child ID="3" name="Joseph"/>
    </childs>
</parent>

This is the external XML file that I use with the document() function:

<?xml version="1.0" encoding="UTF-8"?>
<report xmlns="http://www.eclipse.org/birt/2005/design">
    <property name="units">in</property>
    <text-property name="displayName">Daisy</text-property>
    <text-property name="text">Just plain text</text-property>
    <propList>
        <prop name="prop1"/>
        <prop name="prop2"/>
        <prop name="prop3"/>
        <prop name="prop4"/>
        <prop name="prop5"/>
    </propList>
</report>

So what I am trying to do is to get the value of the text-property element which attribute value is displayName, and then count the number of prop elements, producing a new child element. This is my XSLT code:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  xmlns:ecd="http://www.eclipse.org/birt/2005/design"
  exclude-result-prefixes="xs ecd"
  expand-text="yes"
  version="3.0">

    <xsl:output indent="yes" />

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:template match="parent/childs/child[last()]">

    <xsl:next-match/>
        <child>
            <xsl:attribute name="ID">
                <xsl:value-of select="count(preceding-sibling::child)+2" />
            </xsl:attribute>
            <xsl:attribute name="name">
                <xsl:value-of select="document('inputStack.xml')/ecd:report/ecd:text-property[@name = 'displayName']"/>
            </xsl:attribute>
            <!--new attribute-->
            <xsl:attribute name="nProps">
                <xsl:value-of select="count(document('inputStack.xml')/ecd:report/ecd:propList/(preceding-sibling::ecd:prop[last()]))+1"/>
            </xsl:attribute>
        </child>
    </xsl:template>

</xsl:stylesheet>

So this is the output I'm getting at the moment:

<?xml version="1.0" encoding="UTF-8"?>
<parent>
    <childs>
        <child ID="1" name="John"/>
        <child ID="2" name="Marie"/>
        <child ID="3" name="Joseph"/>
        <child ID="4" name="Daisy" nProps="1"/>
    </childs>
</parent>

As you can see, I'm getting the value of the attribute name right (Daisy) but the value of the attribute nProps is wrong, as it should be 5,

Am I doing anything wrong in the XPATH inside the count function?

Thank you!

Alexandre Jacinto

fobisthename
  • 165
  • 1
  • 10
  • 1
    What does `count(document('inputStack.xml')/ecd:report/ecd:propList/ecd:prop)` give? Trying to understand the logic behind applying the `preceding-sibling` axis. – Aniket V Jul 13 '18 at 10:41
  • @AniketV I am trying to count the number of prop elements, so thats why I'm using the preceding-sibling axis in the prop[last()], so that it gives me all siblings that come before the last prop element, and then do that I add +1 – fobisthename Jul 13 '18 at 10:50
  • @imran I'm not trying to count the child elements, I'm trying to count the prop elements in the external file – fobisthename Jul 13 '18 at 10:51
  • 1
    What's wrong with just doing `count(document('inputStack.xml')/ecd:report/ecd:propList/ecd:prop)`? – Tim C Jul 13 '18 at 10:51
  • 2
    @TimC I don't know why I was complicating it so much, thank you, that worked! – fobisthename Jul 13 '18 at 10:54

1 Answers1

1

The expression ecd:propList/(preceding-sibling::ecd:prop[last()]) selects nothing (an empty node-set) because the ecd:propList element does not have any preceding siblings named ecd:prop.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164