Search code examples
xslt-2.0

why am I getting Required cardinality of value of variable $depts is exactly one; supplied value has cardinality more than one


Trying to figure out some homework here and the online teacher has never responded to any questions I ask. I keep getting an error when I try to process the xml document. "XTTE0570: Required cardinality of value of variable $depts is exactly one; supplied value has cardinality more than one"

The case problem instructions:

  1. First, create a template named getemployees.

  2. Within the getEmployees template, create a variable named depts containing a sequence of the following text strings representing the department codes for Lucy’s sample data: ‘a00’, ‘c01’, ‘d11’, ‘d21’, ‘e11’, and ‘e21’.

  3. After the line to create the depts variable, create the departments element.

  4. Within the departments element, insert a for-each loop that loops through each entry in the depts sequence.

  5. For each entry in the depts sequence do the following:

    a. Create a variable named currentDept equal to the current item in the depts sequence.

    b. Create an element named department with an attribute named deptiD whose value is equal to the value of the currentDept variable.

    c. Use the doc() function to reference the “deptcurrent.xml” file, where current is the value of the currentDept variable. (Hint: Use the concat() function to combine the text strings for “dept”, the currentDept variable, and the text string “.xml”.)

    d. Use the copy-of element to copy the contents of the employees element and its descendants to the department element.

  6. Save your changes to the file and then use your XSLT 2.0 processor to generate the result document horizons.xml by applying the getEmployees template within the alldepartments.xsl style sheet.

<xsl:stylesheet version="2.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:xs="http://www.w3.org/2001/XMLSchema"
     exclude-result-prefixes="xs">


<xsl:output method="xml" encoding="UTF-8" indent="yes" />

<xsl:template name="getEmployees">
  <xsl:variable name="depts" select="('a00', 'c01', 'd11', 'd21', 'e11', 'e21')" as="xs:string" />
  <departments>
    <xsl:for-each select="$depts">
      <xsl:variable name="currentDept">
        <xsl:value-of select="." />
      </xsl:variable>

      <department deptID="{$currentDept}">
        <xsl:value-of select="doc(concat('dept',$currentDept, '.xml'))" />
        <xsl:copy-of select="employees" />
      </department>
    </xsl:for-each>
  </departments>
</xsl:template>

</xsl:stylesheet>

Should generate something similar to:

<?xml version="1.0" encoding="UTF-8"?>
<departments>
   <department dept="a00">
      <employees>
         <employee empID="10">
            <firstName>Marylin</firstName>
            <middleInt>A</middleInt>
            <lastName>Johnson</lastName>
            <department>A00</department>
            <phone>3978</phone>
            <email>[email protected]/horizons</email>
            <dateHired>2000-01-01</dateHired>
            <title>President</title>
            <edLevel>18</edLevel>
            <gender>F</gender>
            <birthDate>1968-08-24</birthDate>
            <salary>121300</salary>
            <bonus>2300</bonus>
            <commission>9700</commission>
         </employee>
         <employee empID="40">
            <firstName>Heather</firstName>
            <middleInt>D</middleInt>
            <lastName>Gordon</lastName>
            <department>A00</department>
            <phone>3915</phone>
            <email>[email protected]/horizons</email>
            <dateHired>2009-03-01</dateHired>
            <title>Manager</title>
            <edLevel>18</edLevel>
            <gender>F</gender>
            <birthDate>1986-06-03</birthDate>
            <salary>85400</salary>
            <bonus>1700</bonus>
            <commission>6500</commission>
         </employee>
      </employees>
   </department>
</departments>

Solution

  • If you use the as attribute on xsl:variable to declare the type of your variable then the value you select needs to fit that declaration, so given that you have a sequence of strings you need to use <xsl:variable name="depts" select="('a00', 'c01', 'd11', 'd21', 'e11', 'e21')" as="xs:string*" />.

    Additionally the

        <xsl:copy-of select="employees" />
    

    inside the for-each over a string sequence doesn't make sense (and explain the error you get after correcting the variable type), there you simply want

        <xsl:copy-of select="doc(concat('dept', ., '.xml'))/employees" />