为什么XSLT只转换第一条记录?

时间:2015-06-25 21:58:38

标签: xml xslt xslt-1.0

我正在使用XSLT 1.0。这是我的3D生命周期XSLT;我还在学习。

我有一个包含多个记录的输入XML文档。

<?xml version="1.0" encoding="UTF-8"?>
<max:QueryNASAPERSONResponse xmlns:max="http://www.ibm.com/maximo" xmlns:msg="http://types.msfc.nasa.gov/personnel/messages/v1/" xmlns:pers="http://types.msfc.nasa.gov/personnel/v1/" xmlns:fn="http://www.w3.org/2005/xpath-functions"
                             xmlns:tns="http://msfc.nasa.gov/asset-query-service/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:typens="http://msfc.nasa.gov/asset-query-service/types/">
    <max:NASAPERSONSet>
        <max:PERSON>
            <max:DEPARTMENT>M-DI</max:DEPARTMENT>
            <max:DISPLAYNAME>AMY</max:DISPLAYNAME>
            <max:DROPPOINT>4201-117B-</max:DROPPOINT>
            <max:FIRSTNAME>AMY</max:FIRSTNAME>
            <max:LASTNAME>BANNISTER</max:LASTNAME>
            <max:LOCATION>4201-117B-</max:LOCATION>
            <max:OWNERSYSID>MIW</max:OWNERSYSID>
            <max:PERSONID>892949451</max:PERSONID>
            <max:PRIMARYEMAIL>AMY.BANNISTER@NASA.GOV</max:PRIMARYEMAIL>
            <max:PRIMARYPHONE>256-544-2331</max:PRIMARYPHONE>
            <max:SENDERSYSID>MIW</max:SENDERSYSID>
            <max:STATUS>ACTIVE</max:STATUS>
            <max:STATUSDATE>2015-06-25T00:00:00-05:00</max:STATUSDATE>
            <max:SUPERVISOR>KAREN VANSANT</max:SUPERVISOR>
            <max:TITLE>AUDITOR</max:TITLE>
            <max:NASAAUID>ABANNIST</max:NASAAUID>
        </max:PERSON>
        <max:PERSON>
            <max:DEPARTMENT>EV74</max:DEPARTMENT>
            <max:DISPLAYNAME>JACK</max:DISPLAYNAME>
            <max:DROPPOINT>OFFSITE--</max:DROPPOINT>
            <max:FIRSTNAME>JACK</max:FIRSTNAME>
            <max:LASTNAME>STOKES</max:LASTNAME>
            <max:LOCATION>OFFSITE--</max:LOCATION>
            <max:OWNERSYSID>MIW</max:OWNERSYSID>
            <max:PERSONID>426512344</max:PERSONID>
            <max:PRIMARYEMAIL>JACK.W.STOKES@NASA.GOV</max:PRIMARYEMAIL>
            <max:PRIMARYPHONE>256-544-1764</max:PRIMARYPHONE>
            <max:SENDERSYSID>MIW</max:SENDERSYSID>
            <max:STATUS>ACTIVE</max:STATUS>
            <max:STATUSDATE>2015-06-25T00:00:00-05:00</max:STATUSDATE>
            <max:SUPERVISOR>
            </max:SUPERVISOR>
            <max:TITLE>ENGINEER</max:TITLE>
            <max:NASAAUID>JSTOKES</max:NASAAUID>
        </max:PERSON>
        <max:PERSON>
            <max:DEPARTMENT>AS10</max:DEPARTMENT>
            <max:DISPLAYNAME>GREGORY</max:DISPLAYNAME>
            <max:DROPPOINT>4249-116D-</max:DROPPOINT>
            <max:FIRSTNAME>GREGORY</max:FIRSTNAME>
            <max:LASTNAME>SMITH</max:LASTNAME>
            <max:LOCATION>4249-116D-</max:LOCATION>
            <max:OWNERSYSID>MIW</max:OWNERSYSID>
            <max:PERSONID>264292430</max:PERSONID>
            <max:PRIMARYEMAIL>GREGORY.D.SMITH@NASA.GOV</max:PRIMARYEMAIL>
            <max:PRIMARYPHONE>256-544-5739</max:PRIMARYPHONE>
            <max:SENDERSYSID>MIW</max:SENDERSYSID>
            <max:STATUS>ACTIVE</max:STATUS>
            <max:STATUSDATE>2015-06-25T00:00:00-05:00</max:STATUSDATE>
            <max:SUPERVISOR>JAMES BANKS</max:SUPERVISOR>
            <max:TITLE>INDUSTRIAL HYGIENIST</max:TITLE>
            <max:NASAAUID>GDSMITH</max:NASAAUID>
        </max:PERSON>
        <max:PERSON>
            <max:DEPARTMENT>IS40</max:DEPARTMENT>
            <max:DISPLAYNAME>STEVE</max:DISPLAYNAME>
            <max:DROPPOINT>4485-114-4-</max:DROPPOINT>
            <max:FIRSTNAME>STEVE</max:FIRSTNAME>
            <max:LASTNAME>KNIGHT</max:LASTNAME>
            <max:LOCATION>4485-114-4-</max:LOCATION>
            <max:OWNERSYSID>MIW</max:OWNERSYSID>
            <max:PERSONID>922600141</max:PERSONID>
            <max:PRIMARYEMAIL>STEVE.E.KNIGHT@NASA.GOV</max:PRIMARYEMAIL>
            <max:PRIMARYPHONE>256-544-2999</max:PRIMARYPHONE>
            <max:SENDERSYSID>MIW</max:SENDERSYSID>
            <max:STATUS>ACTIVE</max:STATUS>
            <max:STATUSDATE>2015-06-25T00:00:00-05:00</max:STATUSDATE>
            <max:SUPERVISOR>RANDALL GOGGANS</max:SUPERVISOR>
            <max:TITLE>SYSTEM ANALYST</max:TITLE>
            <max:NASAAUID>SEKNIGHT</max:NASAAUID>
        </max:PERSON>

我有一个XSLT来转换它,但它只转换来自这个XML的第一条记录。

以下是XSLT:

<?xml version='1.0' ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:mro="http://www.ibm.com/maximo" 
xmlns:max="http://www.ibm.com/maximo" 
xmlns:msg="http://types.msfc.nasa.gov/personnel/messages/v1/" 
xmlns:pers="http://types.msfc.nasa.gov/personnel/v1/" 
xmlns:fn="http://www.w3.org/2005/xpath-functions" 
xmlns:tns="http://msfc.nasa.gov/asset-query-service/" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xmlns:typens="http://msfc.nasa.gov/personnel/types/">
    <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="UTF-8"/>
    <xsl:template match="/*">
        <InvokeNASAPERSONResponse xmlns="http://www.ibm.com/maximo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
            <NASAPERSONSet>
                <PERSON>
                    <DEPARTMENT>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:DEPARTMENT"/>
                    </DEPARTMENT>
                    <DISPLAYNAME>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:DISPLAYNAME"/>
                    </DISPLAYNAME>
                    <DROPPOINT>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:DROPPOINT"/>
                    </DROPPOINT>
                    <FIRSTNAME>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:FIRSTNAME"/>
                    </FIRSTNAME>
                    <LASTNAME>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:LASTNAME"/>
                    </LASTNAME>
                    <LOCATION>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:LOCATION"/>
                    </LOCATION>
                    <OWNERSYSID>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:OWNERSYSID"/>
                    </OWNERSYSID>
                    <PERSONID>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:PERSONID"/>
                    </PERSONID>
                    <PRIMARYEMAIL>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:PRIMARYEMAIL"/>
                    </PRIMARYEMAIL>
                    <PRIMARYPHONE>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:PRIMARYPHONE"/>
                    </PRIMARYPHONE>
                    <SENDERSYSID>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:SENDERSYSID"/>
                    </SENDERSYSID>
                    <STATUS>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:STATUS"/>
                    </STATUS>
                    <STATUSDATE>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:STATUSDATE"/>
                    </STATUSDATE>
                    <SUPERVISOR>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:SUPERVISOR"/>
                    </SUPERVISOR>
                    <TITLE>
                        <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:TITLE"/>
                    </TITLE>
                    <PHONE>
                        <PHONENUM>
                            <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:PRIMARYPHONE"/>
                        </PHONENUM>
                        <ISPRIMARY>
                            <xsl:text>Y</xsl:text>
                        </ISPRIMARY>
                    </PHONE>
                    <EMAIL>
                        <EMAILADDRESS>
                            <xsl:value-of select="max:NASAPERSONSet/max:PERSON/max:PRIMARYEMAIL"/>
                        </EMAILADDRESS>
                    </EMAIL>
                </PERSON>               
            </NASAPERSONSet>
        </InvokeNASAPERSONResponse>
    </xsl:template>
</xsl:stylesheet>

我得到的输出XML文件是:

<InvokeNASAPERSONResponse xmlns:max="http://www.ibm.com/maximo" xmlns:msg="http://types.msfc.nasa.gov/personnel/messages/v1/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions" xmlns:tns="http://msfc.nasa.gov/asset-query-service/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.ibm.com/maximo" xmlns:pers="http://types.msfc.nasa.gov/personnel/v1/" xmlns:mro="http://www.ibm.com/maximo" xmlns:typens="http://msfc.nasa.gov/personnel/types/">
  <NASAPERSONSet>
    <PERSON>
      <DEPARTMENT>M-DI</DEPARTMENT>
      <DISPLAYNAME>AMY</DISPLAYNAME>
      <DROPPOINT>4201-117B-</DROPPOINT>
      <FIRSTNAME>AMY</FIRSTNAME>
      <LASTNAME>BANNISTER</LASTNAME>
      <LOCATION>4201-117B-</LOCATION>
      <OWNERSYSID>MIW</OWNERSYSID>
      <PERSONID>892949451</PERSONID>
      <PRIMARYEMAIL>AMY.BANNISTER@NASA.GOV</PRIMARYEMAIL>
      <PRIMARYPHONE>256-544-2331</PRIMARYPHONE>
      <SENDERSYSID>MIW</SENDERSYSID>
      <STATUS>ACTIVE</STATUS>
      <STATUSDATE>2015-06-25T00:00:00-05:00</STATUSDATE>
      <SUPERVISOR>KAREN VANSANT</SUPERVISOR>
      <TITLE>AUDITOR</TITLE>
      <PHONE>
        <PHONENUM>256-544-2331</PHONENUM>
        <ISPRIMARY>Y</ISPRIMARY>
      </PHONE>
      <EMAIL>
        <EMAILADDRESS>AMY.BANNISTER@NASA.GOV</EMAILADDRESS>
      </EMAIL>
    </PERSON>
  </NASAPERSONSet>
</InvokeNASAPERSONResponse>

这是我输出文件中的唯一记录。如何让它循环遍历XML中的所有记录?

1 个答案:

答案 0 :(得分:3)

您的模板仅匹配一个元素并仅为其输出XML。您希望迭代(使用xsl:for-each),或者更好地,递归地应用模式匹配(使用xsl:apply templates)。

让我们选择xsl:apply-templates,因为它是优雅使用XSLT功能的首选方式......

使用两个模板:

  1. 与您所拥有的相似,以匹配更大的 max:InvokeNASAPERSONResponsemax:NASAPERSONSet上下文:

    <xsl:template match="max:QueryNASAPERSONResponse/max:NASAPERSONSet">
      <InvokeNASAPERSONResponse xmlns="http://www.ibm.com/maximo"
                              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        <NASAPERSONSet>
          <xsl:apply-templates/>
        </NASAPERSONSet>
      </InvokeNASAPERSONResponse>
    </xsl:template>
    
  2. 匹配每个max:PERSON的新模板。

    <xsl:template match="max:PERSON">
      <InvokeNASAPERSONResponse xmlns="http://www.ibm.com/maximo"
                                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <!- ... -->
    
  3. 注意两者是如何通过xsl:apply-templates绑定在一起的,这会重新启动与max:NASAPERSONSet子项的匹配过程。

    在调整后的XSLT中,它们完全相同:

    <?xml version='1.0' ?>
    <xsl:stylesheet version="1.0"
                    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                    xmlns:mro="http://www.ibm.com/maximo" 
                    xmlns:max="http://www.ibm.com/maximo" 
                    xmlns:msg="http://types.msfc.nasa.gov/personnel/messages/v1/" 
                    xmlns:pers="http://types.msfc.nasa.gov/personnel/v1/" 
                    xmlns:fn="http://www.w3.org/2005/xpath-functions" 
                    xmlns:tns="http://msfc.nasa.gov/asset-query-service/" 
                    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
                    xmlns:typens="http://msfc.nasa.gov/personnel/types/">
      <xsl:output method="xml" omit-xml-declaration="yes" indent="yes" encoding="UTF-8"/>
    
      <xsl:template match="max:QueryNASAPERSONResponse/max:NASAPERSONSet">
        <InvokeNASAPERSONResponse xmlns="http://www.ibm.com/maximo"
                                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <NASAPERSONSet>
            <xsl:apply-templates/>
          </NASAPERSONSet>
        </InvokeNASAPERSONResponse>
      </xsl:template>
    
      <xsl:template match="max:PERSON">
        <InvokeNASAPERSONResponse xmlns="http://www.ibm.com/maximo"
                                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <NASAPERSONSet>
            <PERSON>
              <DEPARTMENT>
                <xsl:value-of select="max:DEPARTMENT"/>
              </DEPARTMENT>
              <DISPLAYNAME>
                <xsl:value-of select="max:DISPLAYNAME"/>
              </DISPLAYNAME>
              <DROPPOINT>
                <xsl:value-of select="max:DROPPOINT"/>
              </DROPPOINT>
              <FIRSTNAME>
                <xsl:value-of select="max:FIRSTNAME"/>
              </FIRSTNAME>
              <LASTNAME>
                <xsl:value-of select="max:LASTNAME"/>
              </LASTNAME>
              <LOCATION>
                <xsl:value-of select="max:LOCATION"/>
              </LOCATION>
              <OWNERSYSID>
                <xsl:value-of select="max:OWNERSYSID"/>
              </OWNERSYSID>
              <PERSONID>
                <xsl:value-of select="max:PERSONID"/>
              </PERSONID>
              <PRIMARYEMAIL>
                <xsl:value-of select="max:PRIMARYEMAIL"/>
              </PRIMARYEMAIL>
              <PRIMARYPHONE>
                <xsl:value-of select="max:PRIMARYPHONE"/>
              </PRIMARYPHONE>
              <SENDERSYSID>
                <xsl:value-of select="max:SENDERSYSID"/>
              </SENDERSYSID>
              <STATUS>
                <xsl:value-of select="max:STATUS"/>
              </STATUS>
              <STATUSDATE>
                <xsl:value-of select="max:STATUSDATE"/>
              </STATUSDATE>
              <SUPERVISOR>
                <xsl:value-of select="max:SUPERVISOR"/>
              </SUPERVISOR>
              <TITLE>
                <xsl:value-of select="max:TITLE"/>
              </TITLE>
              <PHONE>
                <PHONENUM>
                  <xsl:value-of select="max:PRIMARYPHONE"/>
                </PHONENUM>
                <ISPRIMARY>
                  <xsl:text>Y</xsl:text>
                </ISPRIMARY>
              </PHONE>
              <EMAIL>
                <EMAILADDRESS>
                  <xsl:value-of select="max:PRIMARYEMAIL"/>
                </EMAILADDRESS>
              </EMAIL>
            </PERSON>               
          </NASAPERSONSet>
        </InvokeNASAPERSONResponse>
      </xsl:template>
    </xsl:stylesheet>