2013-02-04 3 views
0

У меня есть XML-файл, в котором перечислены классы в рамках программы степени. Я создал XSLT (с помощью), который успешно создает группы классов под именем степени. Но клиент хочет третьего уровня, который идентифицирует выборные и недифференцируемые классы. Поле выборки указано с данными «Y», если оно является выборным, и «N», если это не так, или иначе «требование программы».Трехуровневая группа, использующая XSLT

Мне нужно добавить еще один уровень в XSLT, который группирует классы под заголовком «Требование к программе», если у него есть «N» в элементе <FlagElectives1>.

Мне кажется, мне нужно создать другой ключ, основанный на этом элементе, справа, а затем создать шаблон, который создает заголовок xsl: text, который говорит либо: «Требование к программе», либо «Выбор программы», но я застрял. Раньше я никогда не делал трехуровневую группировку.

Вот мой XSLT:

<?xml version="1.0"?> 
<!-- DWXMLSource="STX049 Catalog parsed.xml" --> 
<!DOCTYPE xsl:stylesheet> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="no"/> 
    <xsl:template match="/"> 

    <CrystalReport> 
     <xsl:apply-templates/> 
    </CrystalReport> 
    </xsl:template> 


    <xsl:key name="degrees-by-title" match="CrystalReport/Group/Group/Group/Details" use="Section/ICCB1" /> 

    <xsl:template match="CrystalReport/Group/Group/Group"> 

    <Degree> 
     <xsl:for-each select="Details[count(. | key('degrees-by-title', Section/ICCB1)[1]) = 1]"> 
     <xsl:sort select="Section/ACADPROGRAMSID1" /> 
     <department> 
      <Degreetitle> 
      <xsl:apply-templates select="Section/ACPGDEGREE1" /> 
      </Degreetitle> 
      <Certtitle> 
      <xsl:apply-templates select="Section/CCD11" /> 
      </Certtitle> 
      <DegreeDesc> 
      <xsl:value-of select="Section/ACPGCOMMENTS1"/> 
      </DegreeDesc> 
      <ICCBcode> 
      <xsl:value-of select="Section/ICCB1"/> 
      </ICCBcode> 
      <ProgramID> 
      <xsl:value-of select="Section/ACADPROGRAMSID1"/> 
      </ProgramID> 
      <xsl:for-each select="key('degrees-by-title', Section/ICCB1)"> 
      <xsl:sort select="Section/FlagElectives1" order="ascending" /> 
      <xsl:sort select="Section/DEPARTMENT11" /> 
      <xsl:sort select="Section/CRSNO1" /> 

      <Details> 
       <class> 
       <deptname> 
        <xsl:value-of select="Section/DEPARTMENT11"/> 
       </deptname> 
       <courseno> 
        <xsl:value-of select="Section/CRSNO1"/> 
       </courseno> 
       <classname> 
        <xsl:value-of select="Section/CRSTITLE1"/> 
       </classname> 
       <classcredit> 
        <xsl:value-of select="Section/CRSMINCRED1"/> 
       </classcredit> 
       <Elective> 
        <xsl:value-of select="Section/FlagElectives1" /> 
       </Elective> 
       </class> 
      </Details> 

      </xsl:for-each> 
     </department> 
     </xsl:for-each> 
    </Degree> 

    </xsl:template> 

    <xsl:template match="Section/ACPGDEGREE1[child::node()]"> 
    <xsl:value-of select="."/> 
    <xsl:text> DEGREE</xsl:text> 
    </xsl:template> 

    <xsl:template match="Section/CCD11[child::node()]"> 
    <xsl:text> CERTIFICATE</xsl:text> 
    </xsl:template> 


</xsl:stylesheet> 

Вот структура моего XML:

<?xml version="1.0" encoding="UTF-8"?> 
<CrystalReport> 
    <Group Level="1"> 
    <Group Level="2"> 
     <Group Level="3"> 
     <Details> 
      <Section> 
      <ACPGDEGREE1>AAS</ACPGDEGREE1> 
      <CCD11/> 
      <ACPGCOMMENTS1>The Accounting program</ACPGCOMMENTS1> 
      <ICCB1>3203</ICCB1> 
      <ACADPROGRAMSID1>ACCOU.AAS</ACADPROGRAMSID1> 
      <CRSNO1>1110</CRSNO1> 
      <ACRBPRINTEDSPEC1/> 
      <ACPGHOMELANGNOTREQDRSN1>General Education</ACPGHOMELANGNOTREQDRSN1> 
      <CRSMINCRED1>2</CRSMINCRED1> 
      <ACPGAREAOFSTUDY1>Accounting</ACPGAREAOFSTUDY1> 
      <CRSTITLE1>Using Computers: An Introduction</CRSTITLE1> 
      <DEPARTMENT11>ACCOU</DEPARTMENT11> 
      <CRSSUBJECT1>CIS</CRSSUBJECT1> 
      <ACRBLABEL1>CIS REQUIREMENT</ACRBLABEL1> 
      <CRSMAXCRED1/> 
      <FlagElectives1>N</FlagElectives1> 
      </Section> 
     </Details> 
     <Details> 
      <Section> 
      <ACPGDEGREE1>AAS</ACPGDEGREE1> 
      <CCD11/> 
      <ACPGCOMMENTS1>The Accounting program</ACPGCOMMENTS1> 
      <ICCB1>3203</ICCB1> 
      <ACADPROGRAMSID1>ACCOU.AAS</ACADPROGRAMSID1> 
      <CRSNO1>1150</CRSNO1> 
      <ACRBPRINTEDSPEC1/> 
      <ACPGHOMELANGNOTREQDRSN1>General Education</ACPGHOMELANGNOTREQDRSN1> 
      <CRSMINCRED1>3</CRSMINCRED1> 
      <ACPGAREAOFSTUDY1>Accounting</ACPGAREAOFSTUDY1> 
      <CRSTITLE1>Intro to Computer</CRSTITLE1> 
      <DEPARTMENT11>ACCOU</DEPARTMENT11> 
      <CRSSUBJECT1>CIS</CRSSUBJECT1> 
      <ACRBLABEL1>CIS</ACRBLABEL1> 
      <CRSMAXCRED1/> 
      <FlagElectives1>Y</FlagElectives1> 
      </Section> 
     </Details> 
     </Group> 
    </Group> 
    </Group> 
</CrystalReport> 

Первый уровень группировки должен быть основан на элементе <DEPARTMENT11>. Название различных степеней и сертификатов находится в поле <ACPGAREAOFSTUDY1> Уникальное поле второго уровня во всем этом <ACADPROGRAMSID1>

Здесь желаемый результат:

<CrystalReport> 
<Degrees> 

<!--group and repeat "Degrees" for-each based on element ACPGAREAOFSTUDY1--> 

<areaofstudy>Accounting</areaofstudy> 
<Degree> 
<department> 

<!--group and repeat "department" for-each based on element ICCB1--> 

    <Degreetitle>AAS DEGREE</Degreetitle> 
    <Certtitle /> 
    <DegreeDesc>The Accounting program</DegreeDesc> 
    <ICCBcode>3203</ICCBcode> 
    <ProgramID>ACCOU.AAS</ProgramID> 

<!--group and repeat "Details" for-each based on element ACADPROGRAMSID1 under titles "Program Requirement" or "Program Elective" based on element "FlagElectives1"--> 

    <h1>Program Requirements</h1> 
    <Details> 
    <class> 
     <deptname>ACCOU</deptname> 
     <courseno>1150</courseno> 
     <classname>Intro to Computer</classname> 
     <classcredit>3</classcredit> 
     <Elective>N</Elective> 
    </class> 
    </Details> 
    <h1>Program Electives</h1> 
    <Details> 
    <class> 
     <deptname>ACCOU</deptname> 
     <courseno>1110</courseno> 
     <classname>Using Computers: An Introduction</classname> 
     <classcredit>2</classcredit> 
     <Elective>Y</Elective> 
    </class> 
    </Details> 
</department> 
</Degree> 
<Degree> 
<department> 
    <Degreetitle>AAS DEGREE</Degreetitle> 
    <Certtitle /> 
    <DegreeDesc>The Accounting program</DegreeDesc> 
    <ICCBcode>3203</ICCBcode> 
    <ProgramID>ACCOU.AAS</ProgramID> 
    <h1>Program Requirements</h1> 
    <Details> 
    <class> 
     <deptname>ACCOU</deptname> 
     <courseno>1150</courseno> 
     <classname>Intro to Computer</classname> 
     <classcredit>3</classcredit> 
     <Elective>Y</Elective> 
    </class> 
    </Details> 
    <h1>Program Electives</h1> 
    <Details> 
    <class> 
     <deptname>ACCOU</deptname> 
     <courseno>1110</courseno> 
     <classname>Using Computers: An Introduction</classname> 
     <classcredit>2</classcredit> 
     <Elective>N</Elective> 
    </class> 
    </Details> 
</department> 
</Degree> 
</Degrees> 
</CrystalReport> 
+0

Не могли бы вы привести нам пример того, как вы хотите, чтобы результат выглядел? – JLRishe

+0

Я вижу, что вы открыли отдельный вопрос для последующего вопроса. Помог ли мой ответ здесь или в другом вопросе, который я ответил (о пространствах имен)? Если да, не могли бы вы назвать их ответами? – JLRishe

+0

Вы обновили ответ на тот же код по другому вопросу? Я буду отмечать это как ответ, если вы это сделаете. Я открыл второй вопрос, потому что некоторые люди не допускают нескольких шагов в вопросах. Один вопрос -> один ответ. Но обновленный XSLT ближе к окончательному решению. –

ответ

0

Я сделал немного очистки на вашем XSLT. Каждый раз, когда у вас есть , вложенный в for-each, это хороший признак того, что ваш XSLT нуждается в рефакторинге. Я думаю, что я понял, что вы имеете в виду, группируя курсы, будь то факультативы или нет (хотя вы не указали, как вы хотите это представить), поэтому я пришел к следующему:

<?xml version="1.0"?> 
<!-- DWXMLSource="STX049 Catalog parsed.xml" --> 
<!DOCTYPE xsl:stylesheet> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="no"/> 
    <xsl:variable name="allSections" 
       select="/CrystalReport/Group/Group/Group/Details/Section" /> 

    <xsl:key name="kArea" match="Section" use="ACPGAREAOFSTUDY1"/> 
    <xsl:key name="kDegree" match="Section" 
      use="concat(ACPGAREAOFSTUDY1, '+', ACPGDEGREE1)" /> 
    <xsl:key name="kDepartment" match="Section" 
      use="concat(ACPGAREAOFSTUDY1, '+', ACPGDEGREE1, '+', ICCB1)" /> 

    <xsl:variable name="degreeFirsts" 
      select="$allSections[generate-id() = 
      generate-id(key('kDegree', 
       concat(ACPGAREAOFSTUDY1, '+', ACPGDEGREE1))[1])]" /> 
    <xsl:variable name="deptFirsts" 
      select="$allSections[generate-id() = 
       generate-id(key('kDepartment', 
       concat(ACPGAREAOFSTUDY1, '+', ACPGDEGREE1, '+', ICCB1))[1])]" /> 


    <xsl:template match="/"> 
    <CrystalReport> 
     <Degrees> 
     <xsl:apply-templates 
      select="$allSections[generate-id() = 
       generate-id(key('kArea', ACPGAREAOFSTUDY1)[1])]" 
      mode="group"/> 
     </Degrees> 
    </CrystalReport> 
    </xsl:template> 

    <xsl:template match="Section" mode="group"> 
    <xsl:variable name="area" select="ACPGAREAOFSTUDY1" /> 
    <areaofstudy> 
     <xsl:value-of select="$area"/> 
    </areaofstudy> 
    <xsl:apply-templates select="$degreeFirsts[ACPGAREAOFSTUDY1 = $area]" 
         mode="degree"/> 
    </xsl:template> 

    <xsl:template match="Section" mode="degree"> 
    <xsl:variable name="area" select="ACPGAREAOFSTUDY1" /> 
    <xsl:variable name="degree" select="ACPGDEGREE1" /> 
    <xsl:text>&#xA;</xsl:text> 
    <Degree> 
     <xsl:apply-templates 
     select="$deptFirsts[ACPGAREAOFSTUDY1 = $area and ACPGDEGREE1 = $degree]" 
     mode="department"> 
     <xsl:sort select="ACADPROGRAMSID1" /> 
     </xsl:apply-templates> 
    </Degree> 
    </xsl:template> 

    <xsl:template match="Section" mode="department"> 
    <department> 
     <Degreetitle> 
     <xsl:apply-templates select="ACPGDEGREE1" /> 
     </Degreetitle> 
     <Certtitle> 
     <xsl:apply-templates select="CCD11" /> 
     </Certtitle> 
     <xsl:text>&#xA;</xsl:text> 
     <DegreeDesc> 
     <xsl:apply-templates select="ACPGCOMMENTS1" /> 
     </DegreeDesc> 
     <xsl:text>&#xA;ICCB Code</xsl:text> 
     <ICCBcode> 
     <xsl:apply-templates select="ICCB1" /> 
     </ICCBcode> 
     <xsl:text> | Field of Study Code: </xsl:text> 
     <ProgramID> 
     <xsl:apply-templates select="ACADPROGRAMSID1" /> 
     </ProgramID> 
     <xsl:variable name="courses" 
       select="key('kDepartment', 
        concat(ACPGAREAOFSTUDY1, '+', ACPGDEGREE1, '+', ICCB1))" /> 

     <xsl:call-template name="CourseGroup"> 
     <xsl:with-param name="courses" select="$courses[FlagElectives1 = 'N']" /> 
     <xsl:with-param name="title" select="'Program Requirements'" /> 
     </xsl:call-template> 

     <xsl:call-template name="CourseGroup"> 
     <xsl:with-param name="courses" select="$courses[FlagElectives1 = 'Y']" /> 
     <xsl:with-param name="title" select="'Program Electives'" /> 
     </xsl:call-template> 
    </department> 
    </xsl:template> 

    <xsl:template name="CourseGroup"> 
    <xsl:param name="courses" /> 
    <xsl:param name="title" /> 

    <xsl:if test="$courses"> 
     <xsl:text>&#xA;</xsl:text> 
     <xsl:value-of select="$title" /> 
     <xsl:apply-templates select="$courses"> 
     <xsl:sort select="FlagElectives1" order="ascending" /> 
     <xsl:sort select="DEPARTMENT11" /> 
     <xsl:sort select="CRSNO1" /> 
     </xsl:apply-templates> 
    </xsl:if> 
    </xsl:template> 

    <xsl:template match="Section"> 
    <xsl:text>&#xA;</xsl:text> 
    <Details> 
     <class> 
     <deptname> 
      <xsl:apply-templates select="DEPARTMENT11" /> 
     </deptname> 
     <xsl:text> </xsl:text> 
     <courseno> 
      <xsl:apply-templates select="CRSNO1" /> 
     </courseno> 
     <xsl:text> </xsl:text> 
     <classname> 
      <xsl:apply-templates select="CRSTITLE1" /> 
     </classname> 
     <xsl:text> </xsl:text> 
     <classcredit> 
      <xsl:apply-templates select="CRSMINCRED1" /> 
     </classcredit> 
     </class> 
    </Details> 
    </xsl:template> 

    <xsl:template match="ACPGDEGREE1/text()"> 
    <xsl:value-of select="concat(., ' DEGREE')"/> 
    </xsl:template> 

    <xsl:template match="CCD11/text()"> 
    <xsl:value-of select="concat(., ' CERTIFICATE')" /> 
    </xsl:template> 
</xsl:stylesheet> 

Избирательное объединение достигается за счет call-template элементов, которые выбирают курсы от того, являются ли они факультативные:

<xsl:variable name="courses" 
       select="key('degrees-by-title', ICCB1)" /> 
    <xsl:call-template name="CourseGroup"> 
    <xsl:with-param name="courses" select="$courses[FlagElectives1 = 'Y']" /> 
    <xsl:with-param name="title" select="'Program Requirements'" /> 
    </xsl:call-template> 

При запуске на своем входе образца, этот XSLT производит:

<CrystalReport> 
    <Degree> 
    <department> 
     <Degreetitle>AAS DEGREE</Degreetitle> 
     <Certtitle /> 
     <DegreeDesc>The Accounting program</DegreeDesc> 
     <ICCBcode>3203</ICCBcode> 
     <ProgramID>ACCOU.AAS</ProgramID> 
     <h1>Program Requirements</h1> 
     <Details> 
     <class> 
      <deptname>ACCOU</deptname> 
      <courseno>1150</courseno> 
      <classname>Intro to Computer</classname> 
      <classcredit>3</classcredit> 
      <Elective>Y</Elective> 
     </class> 
     </Details> 
     <h1>Program Electives</h1> 
     <Details> 
     <class> 
      <deptname>ACCOU</deptname> 
      <courseno>1110</courseno> 
      <classname>Using Computers: An Introduction</classname> 
      <classcredit>2</classcredit> 
      <Elective>N</Elective> 
     </class> 
     </Details> 
    </department> 
    </Degree> 
</CrystalReport> 

Обратите внимание на элементы h1, указывающие начало требования и выборные группы. Если вы хотите, чтобы это представляло какой-то другой способ, пожалуйста, уточните это.

+0

Извините, я сейчас полностью смущен. Я никогда не использовал этот метод раньше. Используя эту таблицу стилей, я теряю все существующие тэги. Ваша таблица стилей дает мне данные, но не возвращает теги для многих элементов. Когда я запускаю его на данных, я получаю ACCOU2200Income Возврат налога Preparation3Y вместо: ACCOU Подготовке Налоговых Деклараций 3 Y Как вернуть тэги в результат? Я также хочу использовать некоторые элементы . Я строю больше шаблонов? –

+0

Вы используете все мои XSLT на своем входе или только некоторые из них? Я сделал модификацию, чтобы сделать XSLT более кратким, выполнив поиск старых имен элементов -> имена новых элементов, но это использует функцию 'document()', и вполне возможно, что ваш XSLT-процессор имеет ограничение на эту функцию. Не могли бы вы рассказать, какой процессор вы используете? – JLRishe

+0

Я считаю, что использую все ваши XSLT, показанные в публикации. Я вижу 97 строк кода. Я запускаю его через Adobe Dreamweaver и Safari. –

Смежные вопросы