XLST / XML:使用<xsl:for-each>将属性与WITHOUT进行比较时拉出不同的节点

时间:2016-07-30 03:34:25

标签: xml xslt nodes

如果有人问我,我很抱歉,但我正试图找到我正在寻找的具体例子。

我正在尝试从我拥有的XML文档中搜索XML节点。这是我的xml

<?xml version="1.0" encoding="UTF-8"?>
<courses>
  <course number="341" credits="4.0">
    <title>Data Structures</title>
    <section number="01" delivery="Classroom">
      <enrollment>15</enrollment>
      <room>EA244</room>
      <instructor>
        <first>Nicole</first>
        <last>Anderson</last>
      </instructor>
    </section>
    <section number="02" delivery="Online">
      <enrollment>10</enrollment>
      <instructor>
        <first>Nicole</first>
        <last>Anderson</last>
      </instructor>
      <instructor>
        <first>Chi-Cheng</first>
        <last>Lin</last>
      </instructor>
    </section>
    <section number="03" delivery="Classroom">
      <enrollment>12</enrollment>
      <room>SH102</room>
      <instructor>
        <first>Mark</first>
        <last>Funk</last>
      </instructor>
    </section>
  </course>

</courses>

我正在使用的XSLT是好的,它提取了MOST部分所需的所有属性和元素,但是存在一些主要缺陷: 1)我需要只提取那些具有交付属性“Classroom”的元素,并且我每个课程都会获得子元素,因为布尔值返回true然后拉下“course”的每个子元素

2)我无法根据报名排序,我认为是因为同样的问题。我无法使用for-each,我已经尝试在XML中查找和理解递归,但是当我尝试使用递归调用时,当我测试我的XSLT时,我得到“null”

<xsl:template match="/">
 <classes>
  <xsl:apply-templates select="courses/course/section" />  
  <xsl:apply-templates select="courses/course" />
</classes>
</xsl:template>

 <xsl:template match="section">
   <xsl:attribute name="count">
     <xsl:value-of select="count(//section[@delivery='Classroom'])" />
   </xsl:attribute>
 </xsl:template>  

<xsl:template match="course">
 <class>
  <xsl:if test="section[@delivery='Classroom']">
    <xsl:attribute name="credits">
      <xsl:value-of select="@credits" />
    </xsl:attribute>
    <xsl:attribute name="room">
      <xsl:value-of select="section/room" />
    </xsl:attribute>
    <enrollment><xsl:value-of select="section/enrollment" /></enrollment>
    <instructor><xsl:copy-of select="section/instructor" /></instructor>
    <number><xsl:value-of select="@number" /></number>
    <title><xsl:value-of select="title" /></title>
    </xsl:if>
   </class>
  </xsl:template>

提前感谢能够/愿意提供帮助的任何人。

编辑:这是我当前的输出:

<?xml version="1.0" encoding="UTF-8"?>
<classes count="4">
  <class credits="4.0" room="EA244">
    <enrollment>15</enrollment>
    <instructor>
      <instructor>
        <first>Nicole</first>
        <last>Anderson</last>
      </instructor>
      <instructor>
        <first>Nicole</first>
        <last>Anderson</last>
      </instructor>
      <instructor>
        <first>Chi-Cheng</first>
        <last>Lin</last>
      </instructor>
      <instructor>
        <first>Mark</first>
        <last>Funk</last>
      </instructor>
    </instructor>
    <number>341</number>
    <title>Data Structures</title>
  </class>
  <class credits="4.0" room="AT102">
    <enrollment>9</enrollment>
    <instructor>
      <instructor>
        <first>Chi-Cheng</first>
        <last>Lin</last>
      </instructor>
      <instructor>
        <first>Mingrui</first>
        <last>Zhang</last>
      </instructor>
    </instructor>
    <number>368</number>
    <title>Introduction to Bioinformatics</title>
  </class>
  <class/>
  <class credits="3.0" room="ST108">
    <enrollment>26</enrollment>
    <instructor>
      <instructor>
        <first>Nicole</first>
        <last>Anderson</last>
      </instructor>
    </instructor>
    <number>385</number>
    <title>Applied Database Management Systems</title>
  </class>
  <class/>
</classes>

所以我遇到的问题是我需要每个课程(来自第一个XML文件)来显示课程学分,数字,以及仅在“课堂”中提供的部分的子节点。它适用于大多数情况,因为所有课程只有一个部分,除了第一部分有三个部分,其中两部分是@ delivery =“Classroom”。那个人给了我课程的所有子元素

编辑2:输出应如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<classes count="4">
  <class credits="4.0" room="AT102">
    <number>368</number>
    <title>Introduction to Bioinformatics</title>
    <enrollment>9</enrollment>
    <instructor>
      <first>Chi-Cheng</first>
      <last>Lin</last>
    </instructor>
    <instructor>
      <first>Mingrui</first>
      <last>Zhang</last>
    </instructor>
  </class>
  <class credits="4.0" room="SH102">
    <number>341</number>
    <title>Data Structures</title>
    <enrollment>12</enrollment>
    <instructor>
      <first>Mark</first>
      <last>Funk</last>
    </instructor>
  </class>
  <class credits="4.0" room="EA244">
    <number>341</number>
    <title>Data Structures</title>
    <enrollment>15</enrollment>
    <instructor>
      <first>Nicole</first>
      <last>Anderson</last>
    </instructor>
  </class>
  <class credits="3.0" room="ST108">
    <number>385</number>
    <title>Applied Database Management Systems</title>
    <enrollment>26</enrollment>
    <instructor>
      <first>Nicole</first>
      <last>Anderson</last>
    </instructor>
  </class>
</classes>

我认为第二个教室没有出现(并创建一个新的类元素)的原因是因为我第一次拉节点时得到的布尔值为true,因为部分[@ delivery ='Classroom']在第一个例子中是正确的。所以它只是立即拉动所有节点。此外,同样的问题导致我的排序给我一个不正确的输出。

1 个答案:

答案 0 :(得分:0)

如果您希望课堂上提供的每个class都有section,那么您应该这样做:

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:strip-space elements="*"/>

<xsl:template match="/courses">
    <xsl:variable name="classroom-sections" select="course/section[@delivery='Classroom']" />
    <classes count="{count($classroom-sections)}">
        <xsl:apply-templates select="$classroom-sections" />  
    </classes>
</xsl:template>

<xsl:template match="section">
    <class credits="{../@credits}" room="{room}">
        <number>
            <xsl:value-of select="../@number" />
        </number>
        <xsl:copy-of select="../title | enrollment | instructor"/>
    </class>
</xsl:template>  

</xsl:stylesheet>

P.S。我不知道你为什么要强调你想要这样做“没有使用<xsl:for-each>”。 xsl:for-each指令是XSLT语言不可或缺的一部分,也可以在这里使用,没有任何不良影响。