如何枚举索引(xsl:key)项?

时间:2009-06-29 17:35:41

标签: xslt

我是xml的新手,抱歉这个愚蠢的问题。我正在尝试创建xsl模板以将Source xml转换为Destination。实际上它已经差不多完成但我不知道如何正确枚举<creator>(目的地xml中的创建者@ affil)。

来源:

<?xml version="1.0" encoding="iso-8859-1"?>
<CREATORS>
  <PERSON ROLE="CONTACT">
    <PREFIX>Prof</PREFIX>
    <FIRST_NAME>Mike</FIRST_NAME>
    <MIDDLE_INITIALS>J</MIDDLE_INITIALS>
    <LAST_NAME>Petrov</LAST_NAME>
    <SUFFIX/>
    <POSITION>Director</POSITION>
    <EMAIL_1>pontorez@pontorez.ru</EMAIL_1>
    <EMAIL_2>webmaster@pontorez.ru</EMAIL_2>
    <URL>www.pontorez.ru</URL>
    <MOBILE_PHONE/>
    <ADDRESS>
      <DEPARTMENT/>
      <ORGANISATION>Example</ORGANISATION>
      <ADDRESS_1>Finch Pavilion</ADDRESS_1>
      <ADDRESS_2>Middle Way</ADDRESS_2>
      <CITY>Oxford</CITY>
      <ZIP>OX9 7LG</ZIP>
      <REGION/>
      <COUNTRY CODE="GB">UK</COUNTRY>
      <PHONE_1>+380 6245 716300</PHONE_1>
      <PHONE_2/>
      <FAX_1>+380 6245 716311</FAX_1>
      <FAX_2/>
    </ADDRESS>
    <FOOTNOTE/>
  </PERSON>
  <PERSON ID="7091" ROLE="AUTHOR">
    <PREFIX>Prof</PREFIX>
    <FIRST_NAME>Mike</FIRST_NAME>
    <MIDDLE_INITIALS>J</MIDDLE_INITIALS>
    <LAST_NAME>Petrov</LAST_NAME>
    <SUFFIX/>
    <POSITION>Director</POSITION>
    <EMAIL_1>pontorez@pontorez.ru</EMAIL_1>
    <EMAIL_2>webmaster@pontorez.ru</EMAIL_2>
    <URL>www.pontorez.ru</URL>
    <MOBILE_PHONE/>
    <ADDRESS>
      <DEPARTMENT/>
      <ORGANISATION>Example</ORGANISATION>
      <ADDRESS_1>Finch Pavilion</ADDRESS_1>
      <ADDRESS_2>Middle Way</ADDRESS_2>
      <CITY>Oxford</CITY>
      <ZIP>OX9 7LG</ZIP>
      <REGION/>
      <COUNTRY CODE="GB">UK</COUNTRY>
      <PHONE_1>+380 6245 716300</PHONE_1>
      <PHONE_2/>
      <FAX_1>+380 6245 716311</FAX_1>
      <FAX_2/>
    </ADDRESS>
    <FOOTNOTE>Author footnote</FOOTNOTE>
  </PERSON>
  <PERSON ID="7094" ROLE="AUTHOR">
    <PREFIX>Mrs</PREFIX>
    <FIRST_NAME>Anne</FIRST_NAME>
    <MIDDLE_INITIALS/>
    <LAST_NAME>Spencer</LAST_NAME>
    <SUFFIX/>
    <POSITION/>
    <EMAIL_1>aspencer@Hardware.co.uk</EMAIL_1>
    <EMAIL_2/>
    <URL/>
    <MOBILE_PHONE/>
    <ADDRESS>
      <DEPARTMENT/>
      <ORGANISATION>Example</ORGANISATION>
      <ADDRESS_1>SEO R&amp;D Programme</ADDRESS_1>
      <ADDRESS_2>Finch Pavilion, Middle Way</ADDRESS_2>
      <CITY>Oxford</CITY>
      <ZIP>OX9 7LG</ZIP>
      <REGION>Oxfordshire</REGION>
      <COUNTRY CODE="GB">UK</COUNTRY>
      <PHONE_1>+380 6245 716300</PHONE_1>
      <PHONE_2/>
      <FAX_1>+380 6245 716311</FAX_1>
      <FAX_2/>
    </ADDRESS>
    <FOOTNOTE/>
  </PERSON>
  <PERSON ID="15756" ROLE="AUTHOR">
    <PREFIX>Mr</PREFIX>
    <FIRST_NAME>Ed</FIRST_NAME>
    <MIDDLE_INITIALS/>
    <LAST_NAME>Gantos</LAST_NAME>
    <SUFFIX/>
    <POSITION>Senior Medical Statistician</POSITION>
    <EMAIL_1>santos@xxx.org.uk</EMAIL_1>
    <EMAIL_2/>
    <URL>http://www.isds.sxo.ac.uk/</URL>
    <MOBILE_PHONE/>
    <ADDRESS>
      <DEPARTMENT>Head of SEO Support</DEPARTMENT>
      <ORGANISATION>Centre for Statistics in Software</ORGANISATION>
      <ADDRESS_1>Pearson College</ADDRESS_1>
      <ADDRESS_2>Linton Road</ADDRESS_2>
      <CITY>Oxford</CITY>
      <ZIP>OX9 6UD</ZIP>
      <REGION/>
      <COUNTRY CODE="GB">UK</COUNTRY>
      <PHONE_1>+380 6245 112404</PHONE_1>
      <PHONE_2/>
      <FAX_1>+380 6245 112424</FAX_1>
      <FAX_2/>
    </ADDRESS>
    <FOOTNOTE/>
  </PERSON>
  <PERSON ID="7092" ROLE="AUTHOR">
    <PREFIX>Dr</PREFIX>
    <FIRST_NAME>Sherry</FIRST_NAME>
    <MIDDLE_INITIALS/>
    <LAST_NAME>Wilson</LAST_NAME>
    <SUFFIX/>
    <POSITION/>
    <EMAIL_1>wilson@Hardware.co.uk</EMAIL_1>
    <EMAIL_2/>
    <URL/>
    <MOBILE_PHONE/>
    <ADDRESS>
      <DEPARTMENT/>
      <ORGANISATION>Example</ORGANISATION>
      <ADDRESS_1>SEO R&amp;D Programme</ADDRESS_1>
      <ADDRESS_2>Finch Pavilion, Middle Way</ADDRESS_2>
      <CITY>Oxford</CITY>
      <ZIP>OX9 7LG</ZIP>
      <REGION>Oxfordshire</REGION>
      <COUNTRY CODE="GB">UK</COUNTRY>
      <PHONE_1>+380 6245 716300</PHONE_1>
      <PHONE_2/>
      <FAX_1>+380 6245 716311</FAX_1>
      <FAX_2/>
    </ADDRESS>
    <FOOTNOTE/>
  </PERSON>
  <GROUP ID="????">
    <GROUP_NAME>Bond team</GROUP_NAME>
    <CONTACT_PERSON>Monica Bond</CONTACT_PERSON>
    <EMAIL_1>mk@Hardware.dk</EMAIL_1>
    <URL/>
    <ADDRESS>
      <DEPARTMENT>Nordic Hardware Centre</DEPARTMENT>
      <ORGANISATION>Creyts, Dept 7512</ORGANISATION>
      <ADDRESS_1>Blegdamsvej 219</ADDRESS_1>
      <ADDRESS_2/>
      <CITY>Copenhagen</CITY>
      <ZIP>2900</ZIP>
      <REGION/>
      <COUNTRY CODE="DK">Denmark</COUNTRY>
      <PHONE_1>+415 7667 7110</PHONE_1>
      <PHONE_2>+415 1234 9429</PHONE_2>
      <FAX_1>+415 7667 7007</FAX_1>
      <FAX_2/>
    </ADDRESS>
    <FOOTNOTE>Group footnote</FOOTNOTE>
  </GROUP>
  <PERSON ID="3" ROLE="AUTHOR">
    <PREFIX>Ms</PREFIX>
    <FIRST_NAME>Monica</FIRST_NAME>
    <MIDDLE_INITIALS/>
    <LAST_NAME>Bond</LAST_NAME>
    <SUFFIX/>
    <POSITION>Director of the Hardware Information Management System</POSITION>
    <EMAIL_1>mk@Hardware.dk</EMAIL_1>
    <EMAIL_2/>
    <URL>www.cc-ims.net</URL>
    <MOBILE_PHONE/>
    <ADDRESS>
      <DEPARTMENT>Nordic Hardware Centre</DEPARTMENT>
      <ORGANISATION>Creyts, Dept 7512</ORGANISATION>
      <ADDRESS_1>Blegdamsvej 219</ADDRESS_1>
      <ADDRESS_2/>
      <CITY>Copenhagen</CITY>
      <ZIP>2900</ZIP>
      <REGION/>
      <COUNTRY CODE="DK">Denmark</COUNTRY>
      <PHONE_1>+415 7667 7110</PHONE_1>
      <PHONE_2>+415 1234 9429</PHONE_2>
      <FAX_1>+415 7667 7007</FAX_1>
      <FAX_2/>
    </ADDRESS>
    <FOOTNOTE/>
  </PERSON>
</CREATORS>

目的地:

<?xml version="1.0" encoding="utf-8"?>
<creatorGroup>
  <creator affil="CD004002-aff-0001" creatorRole="author">
    <forenames>Mike</forenames>
    <surnamePrefix>J</surnamePrefix>
    <surname>Petrov</surname>
    <note id="CD004002-note-0001">
      <p>Author footnote</p>
    </note>
  </creator>
  <creator affil="CD004002-aff-0001" creatorRole="author">
    <forenames>Anne</forenames>
    <surname>Spencer</surname>
  </creator>
  <creator affil="CD004002-aff-0002" creatorRole="author">
    <forenames>Ed</forenames>
    <surname>Gantos</surname>
  </creator>
  <creator affil="CD004002-aff-0001" creatorRole="author">
    <forenames>Sherry</forenames>
    <surname>Wilson</surname>
  </creator>
  <creator affil="CD004002-aff-0003" type="collaboration" creatorRole="author">
    <collab>Bond team</collab>
  </creator>
  <creator affil="CD004002-aff-0003" creatorRole="author">
    <forenames>Monica</forenames>
    <surname>Bond</surname>
  </creator>
  <creator affil="CD004002-aff-0001" creatorRole="contact">
    <honorifics>Prof</honorifics>
    <forenames>Mike</forenames>
    <surnamePrefix>J</surnamePrefix>
    <surname>Petrov</surname>
    <jobTitle>Director</jobTitle>
    <email>pontorez@pontorez.ru</email>
    <email>webmaster@pontorez.ru</email>
  </creator>
  <affiliation id="CD004002-aff-0001" countryCode="GB">
    <orgName>Example</orgName>
    <address>
      <street>Finch Pavilion</street>
      <street>Middle Way</street>
      <city>Oxford</city>
      <country>UK</country>
      <postCode>OX9 7LG</postCode>
    </address>
  </affiliation>
  <affiliation id="CD004002-aff-0002" countryCode="GB">
    <orgName>Centre for Statistics in Software</orgName>
    <orgDiv>Head of SEO Support</orgDiv>
    <address>
      <street>Pearson College</street>
      <street>Linton Road</street>
      <city>Oxford</city>
      <country>UK</country>
      <postCode>OX9 6UD</postCode>
    </address>
  </affiliation>
  <affiliation id="CD004002-aff-0003" countryCode="DK">
    <collabContact>Monica Bond</collabContact>
    <orgName>Creyts, Dept 7512</orgName>
    <orgDiv>Nordic Hardware Centre</orgDiv>
    <address>
      <street>Blegdamsvej 219</street>
      <city>Copenhagen</city>
      <country>Denmark</country>
      <postCode>2900</postCode>
    </address>
  </affiliation>
</creatorGroup>

我创建的XSL样式表:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>

  <xsl:key name="affiliations" match="ORGANISATION" use="."/>

  <xsl:template name="kreator">
    <xsl:variable name="affid">
      <!-- The numbering problem is in the below line: -->
      <xsl:number format="0001" value="position()"/>
    </xsl:variable>

    <xsl:variable name="role">
      <xsl:choose>
        <xsl:when test="@ROLE='AUTHOR' or name()='GROUP'">author</xsl:when>
        <xsl:otherwise>contact</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>

    <creator affil="CD004002-aff-{$affid}">
      <xsl:if test="GROUP_NAME!=''">
        <xsl:attribute name="type">collaboration</xsl:attribute>
      </xsl:if>
      <xsl:attribute name="creatorRole">
        <xsl:value-of select="$role"/>
      </xsl:attribute>
      <xsl:if test="$role='contact'">
        <honorifics>
          <xsl:value-of select="PREFIX"/>
        </honorifics>
      </xsl:if>
      <xsl:if test="GROUP_NAME!=''">
        <collab>
          <xsl:value-of select="GROUP_NAME"/>
        </collab>
      </xsl:if>
      <xsl:if test="FIRST_NAME">
        <forenames>
          <xsl:value-of select="FIRST_NAME"/>
        </forenames>
      </xsl:if>
      <xsl:if test="MIDDLE_INITIALS!=''">
        <surnamePrefix>
          <xsl:value-of select="MIDDLE_INITIALS"/>
        </surnamePrefix>
      </xsl:if>
      <xsl:if test="LAST_NAME">
        <surname>
          <xsl:value-of select="LAST_NAME"/>
        </surname>
      </xsl:if>
      <xsl:if test="FOOTNOTE!='' and name()='PERSON'">
        <note id="CD004002-note-{$affid}">
          <p>
            <xsl:value-of select="FOOTNOTE"/>
          </p>
        </note>
      </xsl:if>
      <xsl:if test="$role='contact'">
        <jobTitle><xsl:value-of select="POSITION"/></jobTitle>
        <email><xsl:value-of select="EMAIL_1"/></email>
        <email><xsl:value-of select="EMAIL_2"/></email>
      </xsl:if>

    </creator>
    <xsl:text>&#xA;&#xA;</xsl:text>

  </xsl:template>

  <xsl:template match="/CREATORS">
    <xmp>
      <creatorGroup>
        <!-- list of creators: -->
        <xsl:for-each select="PERSON[@ROLE='AUTHOR'] | GROUP">
          <xsl:call-template name="kreator"/>
        </xsl:for-each>
        <xsl:for-each select="PERSON[@ROLE='CONTACT']">
          <xsl:call-template name="kreator"/>
        </xsl:for-each>
        <!-- list of affiliations: -->
        <xsl:for-each select="//ORGANISATION[generate-id(.)=generate-id(key('affiliations', .))]">
          <affiliation>
            <xsl:attribute name="id">
              CD004002-aff-000<xsl:value-of select="position()"/>
            </xsl:attribute>
            <xsl:attribute name="countryCode">
              <xsl:value-of select="../COUNTRY/@CODE"/>
            </xsl:attribute>
            <xsl:if test="../../CONTACT_PERSON">
              <collabContact>
                <xsl:value-of select="../../CONTACT_PERSON"/>
              </collabContact>
            </xsl:if>
            <orgName>
              <xsl:value-of select="."/>
            </orgName>
            <xsl:if test="../DEPARTMENT!=''">
              <orgDiv>
                <xsl:value-of select="../DEPARTMENT"/>
              </orgDiv>
            </xsl:if>
            <address>
              <street>
                <xsl:value-of select="../ADDRESS_1"/>
              </street>
              <xsl:if test="../ADDRESS_2!=''">
                <street>
                  <xsl:value-of select="../ADDRESS_2"/>
                </street>
              </xsl:if>

              <city>
                <xsl:value-of select="../CITY"/>
              </city>
              <country>
                <xsl:value-of select="../COUNTRY"/>
              </country>
              <postCode>
                <xsl:value-of select="../ZIP"/>
              </postCode>
            </address>
          </affiliation>
          <xsl:text>&#xA;&#xA;</xsl:text>
        </xsl:for-each>
      </creatorGroup>
    </xmp>
  </xsl:template>

</xsl:stylesheet>

即。我想得到<creator>编号,如下所示:

<creator affil="CD004002-aff-0001" creatorRole="author"/>
<creator affil="CD004002-aff-0001" creatorRole="author"/>
<creator affil="CD004002-aff-0002" creatorRole="author"/>
<creator affil="CD004002-aff-0001" creatorRole="author"/>
<creator affil="CD004002-aff-0003" type="collaboration" creatorRole="author"/>
<creator affil="CD004002-aff-0003" creatorRole="author"/>
<creator affil="CD004002-aff-0001" creatorRole="contact"/>

虽然我目前的XSL样式表产生了错误的@ affil's:

<creator affil="CD004002-aff-0004" creatorRole="author"/>
<creator affil="CD004002-aff-0004" creatorRole="author"/>
<creator affil="CD004002-aff-0001" creatorRole="author"/>
<creator affil="CD004002-aff-0004" creatorRole="author"/>
<creator affil="CD004002-aff-0002" type="collaboration" creatorRole="author"/>
<creator affil="CD004002-aff-0002" creatorRole="author"/>
<creator affil="CD004002-aff-0004" creatorRole="contact"/>
你能帮忙吗?感谢。

1 个答案:

答案 0 :(得分:2)

当你这样做时,你的问题是:

<xsl:call-template name="kreator" />

然后您在当前正在处理的<PERSON><GROUP>的上下文中执行此操作。

这意味着position()会告诉您这些元素的位置。它无法神奇地知道您对与当前匹配的第一个<ORGANISATION>的位置感兴趣。

表示您必须以与计算<ORGANISATION>属性<affiliation>的方式相同的方式迭代所有@id

<xsl:variable name="affid">
  <xsl:variable name="org" select="ADDRESS/ORGANISATION" />
  <xsl:for-each select="//ORGANISATION[
    generate-id()
    =
    generate-id(key('affiliations', .)[1])
  ]">
    <xsl:if test=". = $org">
      <xsl:number format="0001" value="position()"/>
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

请注意使用<xsl:if>来确保变量最终只包含一个值,即使您正在查看所有这些值。

对于较大的文档,您可以引入另一个键:

<xsl:key name="organisations" match="ORGANISATION" use="'all'" />

并将其用作所有效率相对较低的“//ORGANISATION”表达式的替代品,例如而不是:

<xsl:for-each select="//ORGANISATION">
  <!-- ... -->
</xsl:for-each>

使用:

<xsl:for-each select="key('organisations', 'all')">
  <!-- ... -->
</xsl:for-each>