Exit from parent loop is not working in XSLT

2019-09-02 17:49发布

问题:

I would like to get one output when condition is met. Here is the sample xml.

<school>
<student_details>
<student>
<id>1</id>
<name>manju</name>
<subject>
<subject_name>english</subject_name>
</subject>
<subject>
<subject_name>maths</subject_name>
</subject>
</student>
<student>
<id>2</id>
<name>raghu</name>
<subject>
<subject_name>social</subject_name>
</subject>
<subject>
<subject_name>maths</subject_name>
</subject>
</student>
<student>
<id>3</id>
<name>vijay</name>
<subject>
<subject_name>maths</subject_name>
</subject>
</student>
<student>
<id>4</id>
<name>sunil</name>
<subject>
<subject_name>social</subject_name>
</subject>
</student>
<student>
<id>5</id>
<name>anil</name>
<subject>
<subject_name>social</subject_name>
</subject>
<subject>
<subject_name>english</subject_name>
</subject>
<subject>
<subject_name>Kannada</subject_name>
</subject>
</student>
</student_details>

<exclude>
<exclude_subjects>
<subject_name>english</subject_name>
</exclude_subjects>
<exclude_subjects> 
<subject_name>maths</subject_name>
</exclude_subjects>
</exculde>
</school>

here is my xsd:

 <schema>
    <element name="school">
    <complexType>
    <sequence>
    <element name="student_details>
<complexType>
    <sequence>
    <element name="student" maxOccurs="unbounded">
    <complexType>
    <sequence>
    <element name="Id" type="sting"/>
    <element name="name" type="sting"/>
    <element name="subject" maxOccurs="unbounded">
    <complexType>
    <sequence>
    <element name="subject_name" type="sting"/>
    </complexType>
    </sequence>
    </element>
    </complexType>
    <sequence>
    </element>
</complexType>
    <sequence>
    </element>

    <element name="exclude">
<complexType>
    <sequence>
    <element name="exclude_subjects" maxOccurs="unbounded">
    <complexType>
    <sequence>
    <element name="subject_name" type="sting"/>
    </complexType>
    </sequence>
    </element>
    </complexType>
    <sequence>
    </element>
</complexType>
    <sequence>
    </element>
    </schema>

here is my xslt which is not working

<xsl:template match="/">
<ns0:xsl:output>
<xsl:for-each select="/ns0:school/ns0:exclude/exclude_subjects>
<variable name="a" select="position"/>
<xsl:for-each select ="../../ns0:student_details/ns0:student"/>
<xsl:for-each select="ns0:subject[not(./ns0:subject_name = ../../../ns0:exclude/ns0:exclude_subjects[$a]/ns0:subject_name)]][1]">
<ns0:result>
<xsl:copy-of select="../ns0:name"/>
</ns0:result>
</ns0:output>
</xsl:template>

My requirement is if student contains any subject which is not there in the exclude_subjects, then that student name should be assigned to the target without duplicate.

For eg: in the above given sample xml,raghu,anil n sunil names should be assigned to the target.

Please help....

回答1:

Try it this way?

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="exclude" match="exclude_subjects" use="subject_name" />

<xsl:template match="/school">
    <output>
        <xsl:for-each select="student_details/student[subject[not(key('exclude', subject_name))]]">
            <xsl:copy-of select="name"/>
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>

Result (after changing </exculde> to </exclude>)

<?xml version="1.0" encoding="UTF-8"?>
<output>
   <name>raghu</name>
   <name>sunil</name>
   <name>anil</name>
</output>

Edit

currently am using BPEL 10g and xsl:key is currently not supported in xslt.

Then you're not really using XSLT. Still, you can achieve the same result using a less efficient method:

<xsl:template match="/school">
    <output>
        <xsl:for-each select="student_details/student[subject[not(subject_name = ../../../exclude/exclude_subjects/subject_name)]]">
            <xsl:copy-of select="name"/>
        </xsl:for-each>
    </output>
</xsl:template>


标签: xml xslt