在XSLT问题中for-each

时间:2017-08-09 13:21:57

标签: xml xslt xpath

我是XSLT的新手,并尝试为每个循环输出,以便每个节点匹配来自不同根的另一个节点。我有以下XML:

<?xml version="1.0" encoding="UTF-8"?>
    <class> 
        <students>
            <student> 
                <firstname>Dinkar</firstname> 
                <teacher_id>1</teacher_id>
            </student> 
            <student > 
                <firstname>Vaneet</firstname> 
                <teacher_id>2</teacher_id>
            </student> 
            <student> 
                <firstname>Jasvir</firstname> 
                <teacher_id>3</teacher_id>
            </student> 
        </students>
        <teachers>
            <teacher>
                <tfirstname>Dima</tfirstname>
                <teacher_id>1</teacher_id>
            </teacher>
            <teacher>
                <tfirstname>Vova</tfirstname>
                <teacher_id>2</teacher_id>
            </teacher>
            <teacher>
                <tfirstname>Denis</tfirstname>
                <teacher_id>3</teacher_id>
            </teacher>
        </teachers>
    </class>

我需要获得以下XML输出:

<?xml version="1.0" encoding="UTF-8"?>
<G2>
   <Student_Name>Dinkar</Student_Name>
   <TName>Dima</TName>
</G2>
<G2>
   <Student_Name>Vaneet</Student_Name>
   <TName>Vova</TName>
</G2>
<G2>
   <Student_Name>Jasvir</Student_Name>
   <TName>Denis</TName>
</G2>

意思是每个学生根据匹配的ID获取教师的姓名。 但是我得到了所有教师的名字:

<?xml version="1.0" encoding="UTF-8"?>
<G2>
   <Student_Name>Dinkar</Student_Name>
   <TName>Dima Vova Denis</TName>
</G2>
<G2>
   <Student_Name>Vaneet</Student_Name>
   <TName>Dima Vova Denis</TName>
</G2>
<G2>
   <Student_Name>Jasvir</Student_Name>
   <TName>Dima Vova Denis</TName>
</G2>

我的XSLT:

<?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"
    exclude-result-prefixes="xs"
    version="2.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <xsl:for-each select="class/students/student">
            <G2>
            <Student_Name><xsl:value-of select="firstname"/></Student_Name>
            <xsl:if test="/class/teachers/teacher/teacher_id=teacher_id">
                <TName><xsl:value-of select="/class/teachers/teacher/tfirstname"/></TName>
            </xsl:if>
            </G2>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>

请你协助。

2 个答案:

答案 0 :(得分:1)

你的指示:

<xsl:value-of select="/class/teachers/teacher/tfirstname"/>

选择所有教师的名字,而不考虑您当前的背景。您想将其更改为有条件的:

<xsl:value-of select="/class/teachers/teacher[teacher_id=current()/teacher_id]/tfirstname"/>

更好的是,将 key 定义为:

<xsl:key name="teacher-by-id" match="teacher" use="teacher_id" />

然后将其用作:

<xsl:value-of select="key('teacher-by-id', teacher_id)/tfirstname"/>

执行查找。如果您只想在查找成功时输出名称,这将特别方便:

<xsl:variable name="teacher" select="key('teacher-by-id', teacher_id)" />
<xsl:if test="$teacher">            
    <TName>
        <xsl:value-of select="$teacher/tfirstname"/>
    </TName>
</xsl:if>

答案 1 :(得分:0)

对代码进行最小的更改,您可以尝试这一点(将teacher_id保存在变量中,以便找到相应的元素)。

<?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"
                exclude-result-prefixes="xs"
                version="2.0">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="/">
        <xsl:for-each select="//student">
            <xsl:variable name="teacher_id">
                <xsl:value-of select="teacher_id"/>
            </xsl:variable>
            <G2>
                <Student_Name><xsl:value-of select="firstname"/></Student_Name>
                <TName><xsl:value-of select="//teacher[teacher_id=$teacher_id]/tfirstname"/></TName>
            </G2>
        </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>