xslt - apply-templates 输出内容的次数超过预期

标签 xslt apply-templates

我是 XSLT 的新手,我不明白为什么根要处理两次(至少这是我对此输出的解释)。

编辑:(我将 Saxon-HE 与 XSLT 2.0 结合使用)但也使用多个在线流程进行了测试,结果始终相同。

XSLT 文件

<?xml version="1.0" encoding="UTF-8"?>
<!-- XResume.xsl: resume.xml ==> resume.xhtml -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xpath-default-namespace="https://github.com/IME-SE8/XResume">

<xsl:output method="html"/>

<xsl:template match="/">

<html>
<head>
  <meta charset="utf-8" />
  <meta lang="en" />
  <meta name="description" content="Personal Resume and Portfolio" />
  <title><xsl:value-of select="resume/personalInformation/name/attribute::shortForm" /> Website</title>
</head>
<body>
  <xsl:apply-templates select="resume"/>
</body>
</html>

</xsl:template>

<xsl:template match="resume">
  <div class="resume">

    <div class="header">
      <div class="name"><xsl:value-of select="personalInformation/name" /></div>
      <div class="contacts">
        <xsl:for-each select="personalInformation/contact">
          <div class="contactInformation">
            <p><xsl:value-of select="organization" /></p>
            <p><xsl:value-of select="address" /></p>
            <p><xsl:value-of select="phoneNumber" /></p>
            <p><xsl:value-of select="email" /></p>
          </div>
        </xsl:for-each>
      </div>
    </div>

    <div class="sections">
      <xsl:apply-templates />
    </div>
  </div>
</xsl:template>


<xsl:template match="interests"></xsl:template>
<xsl:template match="education"></xsl:template>
<xsl:template match="skills"></xsl:template>
<xsl:template match="experiences"></xsl:template>
<xsl:template match="projects"></xsl:template>
<xsl:template match="awards"></xsl:template>

</xsl:stylesheet>

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl"
href="https://github.com/IME-SE8/XResume/master/XResume.xsl"?>
<resume 
xmlns="https://github.com/IME-SE8/XResume" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://github.com/IME-SE8/XResume XResume.xsd">

    <personalInformation>
        <name first="John" last="Doe" shortForm="JD">John Doe</name>
        <contact type="institutional">
            <organization>StackOverflow Institute of Technology</organization>
            <address>Internet</address>
            <phoneNumber>+1 (666) 666-9999</phoneNumber>
            <email>john@d.oe</email>
        </contact>
    </personalInformation>


    <interests>
        <interest>Q and A</interest>
        <interest>XSLT</interest>
    </interests>

    <education></education>

    <skills></skills>

    <experiences></experiences>

    <projects></projects>

    <awards></awards>

</resume>

HTML 输出

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <meta charset="utf-8">
      <meta lang="en">
      <meta name="description" content="Personal Resume and Portfolio">
      <title>JD Website</title>
   </head>
   <body>
      <div class="resume">
         <div class="header">
            <div class="name">John Doe</div>
            <div class="contacts">
               <div class="contactInformation">
                  <p>StackOverflow Institute of Technology</p>
                  <p>Internet</p>
                  <p>+1 (666) 666-9999</p>
                  <p>john@d.oe</p>
               </div>
            </div>
         </div>
         <div class="sections">


                    John Doe

                        StackOverflow Institute of Technology
                        Internet
                        +1 (666) 666-9999
                        john@d.oe

















         </div>
      </div>
   </body>
</html>

(是的,有那么多空行)

输出 header div 非常好,但是在 sections div 内部 apply-templates 呈现 中的所有信息div header 再次但没有 HTML 标签。

我是否遗漏了任何 XSLT 处理细节?模板匹配是否以匹配元素现在被视为根或类似元素的方式设置上下文?

最佳答案

问题出在这里:

<div class="sections">
  <xsl:apply-templates />
</div>

这会将模板应用于当前节点 (resume) 的所有子节点,包括 personalInformation 元素。

由于没有为 personalInformation 指定匹配模板,XSLT 处理器使用内置 XSLT 模板,应用它们会导致输出 personalInformation 所有后代文本节点的串联 元素。

解决方案:

替换:

<div class="sections">
  <xsl:apply-templates />
</div>

与:

<div class="sections">
  <xsl:apply-templates select="*[not(self::personalInformation)]" />
</div>

转换的结果现在不包含有问题的输出:

<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <meta charset="utf-8">
      <meta lang="en">
      <meta name="description" content="Personal Resume and Portfolio">
      <title>JD Website</title>
   </head>
   <body>
      <div class="resume">
         <div class="header">
            <div class="name">John Doe</div>
            <div class="contacts">
               <div class="contactInformation">
                  <p>StackOverflow Institute of Technology</p>
                  <p>Internet</p>
                  <p>+1 (666) 666-9999</p>
                  <p>john@d.oe</p>
               </div>
            </div>
         </div>
         <div class="sections"></div>
      </div>
   </body>
</html>

关于xslt - apply-templates 输出内容的次数超过预期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33094028/

相关文章:

xslt - 什么是node()的显式版本

xslt - XSL套用范本无法运作...可能是XPath错误

xml - 在同一级别为同一 XML 元素呈现不同的模板

xslt - 使用XPath选择具有特定属性值的连续元素

xslt - 为什么XSLT意外更改上下文?

java - 使用已编译的 XSL 转换

html - 使用 XSL 删除不需要的标签

xslt - XSLT 2.0 中的序列构造函数是什么?