【问题标题】:XML XSLT -> HTML Transformation - How to split xml element text into dot points with xsltXML XSLT -> HTML 转换 - 如何使用 xslt 将 xml 元素文本拆分为点
【发布时间】:2015-04-04 18:15:09
【问题描述】:

我有一个 XML 数据结构,我正在使用 XSLT 将其转换为 HTML。我需要使用 XSLT 和输出将 XML 的 current_teaching 元素中的文本拆分为点(元素内容中的分号表示我希望在哪里进行拆分)。

到目前为止,这就是我所拥有的。

XML/XSLT 文件:

        <?xml version="1.0" encoding="UTF-8"?>
    <?xml-stylesheet type="text/xsl" href="StaffList.xslt"?>
    <StaffList>
        <StaffMember>
            <title>Dr John Brown</title>
            <titledesc>Senior Lecturer, ICU Security Research Institute</titledesc>       <!-- example text --> 
            <telephone>(645) 2545 6988</telephone>
            <mobile>04568 6665 666</mobile>
            <facsimile>(61 8) 9999 9999</facsimile>
            <email>dr.brown@brown.com</email>
            <campus>Mountain Range</campus> 
            <room>18.13</room>
            <description>John Brown is a awesome doctor.</description>
            <current_teaching>Data Structures; Principles of Distributed Systems; Fundamentals of Software Engineering</current_teaching> 
        </StaffMember>
    </StaffList>

XSLT:



   <?xml version="1.0" encoding="ISO-8859-1"?>
    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
     <html>
      <head>
              <link rel="stylesheet" type="text/css" href="StaffList.css"/>
     </head>
     <body>
       <xsl:for-each select="StaffList/StaffMember">
        <h2 id="title"><xsl:value-of select="title"/></h2>
        <h3 id="titledesc"><xsl:value-of select="titledesc"/></h3>
        <br></br>
       <table>
         <tr>
         <td id="telephone_1">Telephone</td>
          <td id="telephone_2"><xsl:value-of select="telephone"/></td>
         </tr>
         <tr>
         <td id="mobile_1">Mobile</td>
         <td id="mobile_2"><xsl:value-of select="mobile"/></td>
        </tr>
        <tr>
        <td id="facsimile_1">Facsimile</td>
        <td id="facsimile_2"><xsl:value-of select="facsimile"/></td>
        </tr>
        <tr>
        <td id="email_1">Email</td>
        <td id="email_2"><xsl:value-of select="email"/></td>
        </tr>
        <tr>
        <td id="campus_1">Campus</td>
        <td id="campus_2"><xsl:value-of select="campus"/></td>
        </tr>
        <tr>
        <td id="room_1">Room</td>
        <td id="room_2"><xsl:value-of select="room"/></td>
        </tr>   
       </table>
       <br></br>
       <br></br>
       <p><xsl:value-of select="description"/></p>
       <br></br>

        </xsl:for-each>
     </body>
     </html>
    </xsl:template></xsl:stylesheet>

我进行了一些搜索,已经找到了一个可能的解决方案,但我无法让我的 XSLT 使用它。 这是我尝试过的:

        <ul>
        <xsl:analyze-string select="string()" regex=".*?[\.;]" flags="sm">
            <xsl:matching-substring>
                <li><xsl:value-of select="."/></li>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <li><xsl:value-of select="."/></li>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </ul>  

这是在上述 XSLT 代码的最后一个 br /br 和 /xsl:for-each 之间添加的。

【问题讨论】:

  • 您的样式表声明了 1.0 版。您正在尝试使用需要 XSLT 2.0 的 xsl:analyze-string。您实际使用的是哪种 XSLT 处理器?
  • 我现在用的是1.0,是不是只要把声明改成2.0那么简单?
  • 不,您需要 XSLT 2.0 处理器才能使用 XSLT 2.0 功能。您使用的是哪个特定的 XSLT 1.0 处理器?如果您不确定,请在此处查看方法:stackoverflow.com/questions/25244370
  • 从该线程中的代码输出是“Microsoft 1”

标签: xml string xslt split


【解决方案1】:

XSLT 1.0 标记化模板可以非常简短,证明&lt;xsl:choose&gt;&lt;xsl:when&gt;&lt;xsl:otherwise&gt; 可以避免:

<xsl:template match="current_teaching/text()[normalize-space()]" name="split">
  <xsl:param name="pText" select="."/>
  <xsl:if test="normalize-space($pText)">
    <li><xsl:value-of select="substring-before(concat($pText, ';'), ';')"/></li>
    <xsl:call-template name="split">
      <xsl:with-param name="pText" select="substring-after($pText, ';')"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

通常会选择执行它,使用代码中的&lt;xsl:apply-templates&gt; 指令,就像这样

   <ul>
     <xsl:apply-templates select="current_teaching"/>
   </ul>

说明: 有助于消除此解决方案中的复杂性的是使用 Sentinel Programming 的原则。 一个标记字符 (;) 被附加到字符串中,这样就无需分析两种不同的情况——文本包含分隔符,文本不包含分隔符。

【讨论】:

    【解决方案2】:

    在 XSLT 1.0(这是 Microsoft 处理器将支持的所有功能)中,您需要调用命名模板来递归处理输入。调用看起来像:

    <ul>
        <xsl:call-template name="tokenize">
            <xsl:with-param name="text" select="current_teaching"/>
        </xsl:call-template>
    </ul>
    

    和命名模板:

    <xsl:template name="tokenize">
        <xsl:param name="text"/>
        <xsl:param name="delimiter" select="'; '"/>
        <xsl:choose>
            <xsl:when test="contains($text, $delimiter)">
                <li>
                    <xsl:value-of select="substring-before($text, $delimiter)"/>
                </li>
                <!-- recursive call -->
                <xsl:call-template name="tokenize">
                    <xsl:with-param name="text" select="substring-after($text, $delimiter)"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <li>
                    <xsl:value-of select="$text"/>
                </li>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-13
      • 1970-01-01
      • 1970-01-01
      • 2014-03-08
      • 2012-09-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多