Java 中文官方教程 2022 版(三十九)(4)

简介: Java 中文官方教程 2022 版(三十九)

Java 中文官方教程 2022 版(三十九)(3)https://developer.aliyun.com/article/1488159

处理剩余的结构元素

在这一部分,您将处理 LISTNOTE 元素,这些元素为文章添加了更多结构。


注意 - 本节描述的示例文档是 article2.xml,用于操作它的样式表是 article2.xsl。结果是 stylizer2.html。解压缩 XSLT examples 到 install-dir/jaxp-1_4_2-release-date/samples 目录后,这些文件可以在 xslt/data 目录中找到。


首先向示例文档添加一些测试数据:

<?xml version="1.0"?>
<ARTICLE>
<TITLE>A Sample Article</TITLE>
 <SECT>The First Major Section
    ...
  </SECT>
  <SECT>The Second Major Section
  <PARA>This section adds a LIST and a NOTE.
    <PARA>Here is the LIST:
      <LIST type="ordered">
        <ITEM>Pears</ITEM>
        <ITEM>Grapes</ITEM>
      </LIST>
  </PARA>
  <PARA>And here is the NOTE:
  <NOTE>Don't forget to go to the 
           hardware store on your way
           to the grocery!
  </NOTE>
  </PARA>
 </SECT> 
</ARTICLE>

注意 - 虽然 XML 文件中的 listnote 包含在各自的段落中,但它们是否包含并不重要;生成的 HTML 无论如何都是相同的。但是包含它们会使它们在面向大纲的编辑器中更容易处理。


修改 处理

接下来,修改 PARA 模板以考虑我们现在允许一些结构元素嵌入到段落中的事实:

<xsl:template match="PARA">
<p> <xsl:apply-templates select=
    "text()|B|I|U|DEF|LINK"/>
 </p>
 <xsl:apply-templates select=
    "PARA|LIST|NOTE"/>
</xsl:template>

这种修改使用了你用于节标题的相同技术。唯一的区别是 SECT 元素不应该出现在段落中。(但是,一个段落很容易存在于另一个段落内,例如,作为引用材料)。

处理 元素

现在你已经准备好添加一个模板来处理 LIST 元素:

<xsl:template match="LIST">
 <xsl:if test="@type='ordered'"> 
  <ol>
   <xsl:apply-templates/>
    </ol>
    </xsl:if>
    <xsl:if test="@type='unordered'">
     <ul>
      <xsl:apply-templates/>
     </ul>
 </xsl:if>
</xsl:template>
</xsl:stylesheet>

标签使用 test="" 属性来指定一个布尔条件。在这种情况下,测试值是 type 属性,并且生成的列表会根据值是有序还是无序而改变。

在这个例子中注意两个重要的事情:

  • 没有 else 子句,也没有 return 或 exit 语句,因此需要两个 标签来覆盖两个选项。(或者可以使用 标签,它提供了 case 语句功能)。
  • 在属性值周围需要使用单引号。否则,XSLT 处理器会尝试将 ordered 作为 XPath 函数来解释,而不是作为字符串。

现在通过处理 ITEM 元素来完成 LIST 处理:

<xsl:template match="ITEM">
 <li><xsl:apply-templates/>
 </li>
 </xsl:template>
</xsl:stylesheet>

在样式表中排序模板

到目前为止,你应该已经了解到模板是彼此独立的,所以它们通常出现在文件中的位置并不重要。因此,从这一点开始,我们只会展示你需要添加的模板。(为了比较,它们总是添加在示例样式表的末尾)。

当两个模板可以应用于同一节点时,顺序确实很重要。在这种情况下,最后定义的模板是被找到和处理的。例如,要将缩进列表的排序更改为使用小写字母表,可以指定一个看起来像这样的模板模式://LIST//LIST。在该模板中,您将使用 HTML 选项生成字母枚举,而不是数字枚举。

但这样的元素也可以通过模式//LIST来识别。为了确保正确处理,指定//LIST的模板必须出现在指定//LIST//LIST的模板之前。

处理元素

唯一剩下的结构元素是NOTE元素。添加以下模板来处理它。

<xsl:template match="NOTE">
 <blockquote><b>Note:</b><br/>
 <xsl:apply-templates/>
 </p></blockquote>
 </xsl:template>
</xsl:stylesheet>

这段代码引发了一个有趣的问题,这是由于包含
标签导致的。为了使文件成为格式良好的 XML,必须在样式表中指定该标签为
,但许多浏览器不识别该标签。虽然大多数浏览器识别序列

,但它们都将其视为段落换行而不是单个换行。

换句话说,转换必须生成一个
标签,但样式表必须指定
。这就是我们在样式表中早期添加的特殊输出标签的主要原因:

<xsl:stylesheet ... >
   <xsl:output method="html"/>
   [...]
</xsl:stylesheet>

该输出规范将空标签(如
)转换为它们的 HTML 形式
,在输出时。这种转换很重要,因为大多数浏览器不识别空标签。以下是受影响的标签列表:

area      frame   isindex
base      hr      link
basefont  img     meta
br        input   param
col

总之,默认情况下,XSLT 在输出时生成格式良好的 XML。因为 XSL 样式表本身就是格式良好的 XML,所以你不能轻易地在其中间放置
这样的标签。标签解决了这个问题,这样你可以在样式表中编码
,但在输出中得到

指定的另一个主要原因是,与指定一样,生成的文本不会被转义。例如,如果样式表包含<实体引用,它将出现为生成文本中的<字符。另一方面,当生成 XML 时,样式表中的<实体引用将保持不变,因此在生成的文本中会显示为<


注意 - 如果你希望<实际上作为 HTML 输出的一部分生成,你需要将其编码为<。这个序列在输出时变为<,因为只有&被转换为&字符。


使用定义了LISTNOTE元素的Stylizer示例运行

  1. 导航到samples目录。
% cd *install-dir*/jaxp-1_4_2-*release-date*/samples.
  1. 点击此链接下载 XSLT 示例,并将其解压缩到install-dir/jaxp-1_4_2-release-date/samples目录中。
  2. 导航到xslt目录。
cd xslt
  1. 编译Stylizer示例。
    输入以下命令:
% javac Stylizer.java
  1. 使用样式表article2.xslarticle2.xml上运行Stylizer示例。
% java Stylizer data/article2.xsl  data/article2.xml
  1. 这是当你现在运行程序时为第二部分生成的 HTML:
...
<h2>The Second Major Section
</h2>
<p>This section adds a LIST and a NOTE.
</p>
<p>Here is the LIST:
</p>
<ol>
<li>Pears</li>
<li>Grapes</li>
</ol>
<p>And here is the NOTE:
</p>
<blockquote>
<b>Note:</b>
<br>Do not forget to go to the hardware store on your way to the grocery!
</blockquote>

处理内联(内容)元素

ARTICLE类型中唯一剩下的标签是内联标签-它们不会在输出中创建换行,而是被整合到它们所属的文本流中。

内联元素与结构元素不同,内联元素是标签内容的一部分。 如果将元素视为文档树中的节点,则每个节点都具有内容和结构。 内容由它包含的文本和内联标记组成。 结构由标签下的其他元素(结构元素)组成。


注意 - 本节描述的示例文档是article3.xml,用于操作它的样式表是article3.xsl。 结果是stylizer3.html


首先向示例文档添加一些测试数据:

<?xml version="1.0"?>
<ARTICLE>
 <TITLE>A Sample Article</TITLE>
  <SECT>The First Major Section
      [...]
  </SECT>
  <SECT>The Second Major Section
      [...]
  </SECT> 
<SECT>The <i>Third</i> 
    Major Section
 <PARA>In addition to the inline tag
    in the heading, 
 this section defines the term  
    <DEF>inline</DEF>,
 which literally means "no line break". 
 It also adds a simple link to the main page 
    for the Java platform 
(<LINK>http://java.sun.com</LINK>),
 as well as a link to the 
 <LINK target="http://java.sun.com/xml">
   XML </LINK> 
 page.
 </PARA>
 </SECT> 
</ARTICLE>

现在处理段落中的内联元素,将它们重命名为 HTML 斜体标记:

<xsl:template match="DEF">
 <i> <xsl:apply-templates/> </i> 
</xsl:template>

接下来,注释掉文本节点规范化。它已经达到了它的目的,现在你需要保留重要的空格:

<!--  
<xsl:template match="text()">
  <xsl:value-of select="normalize-space()"/>
   </xsl:template>
-->

这个修改使我们不会丢失在和等标签之前的空格。 (尝试在没有此修改的情况下运行程序,看看结果)。

现在处理基本的内联 HTML 元素,如,和,用于加粗,斜体和下划线。

<xsl:template match="B|I|U">
 <xsl:element name="{name()}">
 <xsl:apply-templates/>
 </xsl:element> 
</xsl:template>

标签允许您计算要生成的元素。 在这里,您使用当前元素的名称生成适当的内联标记。 特别要注意在name=".."表达式中使用大括号({})。 这些大括号导致引号内的文本被处理为 XPath 表达式,而不是被解释为字面字符串。 在这里,它们导致 XPath name()函数返回当前节点的名称。

大括号可以出现在属性值模板可以出现的任何地方。 (属性值模板在 XSLT 规范的第 7.6.2 节中定义,并且它们出现在模板定义的几个地方)。 在这种表达式中,大括号也可以用于引用属性的值,{@foo},或元素的内容{foo}


注意 - 您还可以使用生成属性。 有关更多信息,请参阅 XSLT 规范的第 7.1.3 节。


最后剩下的元素是LINK标签。处理该标签的最简单方法是设置一个带有参数的命名模板:

<xsl:template name="htmLink">
 <xsl:param name="dest" 
    select="UNDEFINED"/> 
 <xsl:element name="a">
 <xsl:attribute name="href">
 <xsl:value-of select=""/>
 </xsl:attribute>
 <xsl:apply-templates/> 
 </xsl:element> 
</xsl:template>

这个模板的主要区别在于,不是指定匹配子句,而是使用name=""子句为模板指定一个名称。 因此,只有在调用它时才会执行此模板。

在模板内部,还使用标签指定一个名为dest的参数。 为了进行一些错误检查,您使用 select 子句为该参数指定了一个默认值UNDEFINED。 要在标签中引用变量,您指定.

`* * *

注意 - 请记住,引号中的条目被解释为表达式,除非它进一步被单引号括起来。 这就是为什么之前需要在"@type='ordered'"中使用单引号来确保 ordered 被解释为字符串。


标签生成一个元素。之前,你可以简单地通过编写类似的代码来指定我们想要的元素。但是在这里,你正在动态生成标签的主体中 HTML 锚点()的内容。并且你正在使用标签动态生成锚点的href属性。

模板的最后一个重要部分是标签,它插入LINK元素下文本节点中的文本。如果没有它,生成的 HTML 链接中将没有文本。

接下来,添加LINK标签的模板,并在其中调用命名模板:

<xsl:template match="LINK">
 <xsl:if test="@target">
 <!--Target attribute specified.-->
 <xsl:call-template 
    name="htmLink">
 <xsl:with-param name="dest" 
    select="@target"/> 
 </xsl:call-template>
 </xsl:if>
</xsl:template>
<xsl:template name="htmLink">
[...]

test="@target"子句在 LINK 标签中存在 target 属性时返回 true。因此,当链接的文本和为其定义的目标不同时,这个标签会生成 HTML 链接。

标签调用命名模板,而使用name子句指定参数,并使用select子句指定其值。

在样式表构建过程的最后一步中,添加标签来处理没有target属性的LINK标签。

<xsl:template match="LINK">
   <xsl:if test="@target">
      [...]
   </xsl:if>
   <xsl:if test="not(@target)">
 <xsl:call-template name="htmLink">
 <xsl:with-param name="dest">
 <xsl:apply-templates/>
 </xsl:with-param>
 </xsl:call-template>
 </xsl:if>
</xsl:template>

not(...)子句反转了先前的测试(记住,没有 else 子句)。因此,当未指定目标属性时,模板的这部分被解释。这次,参数值不是来自select子句,而是来自元素的内容。


注意 - 仅仅是为了明确:参数和变量(稍后在 XSLT 还能做什么?中讨论)的值可以通过select子句指定,让你可以使用 XPath 表达式,也可以通过元素的内容指定,让你可以使用 XSLT 标签。


在这种情况下,参数的内容是由标签生成的,它插入LINK元素下文本节点的内容。

运行带有内联元素定义的Stylizer示例

  1. 导航到samples目录。
% cd *install-dir*/jaxp-1_4_2-*release-date*/samples.
  1. 点击此链接下载 XSLT 示例并将其解压缩到install-dir/jaxp-1_4_2-release-date/samples目录。
  2. 导航到xslt目录。
cd xslt
  1. 编译Stylizer示例。
    输入以下命令:
% javac Stylizer.java
  1. 使用样式表article3.xslarticle3.xml上运行Stylizer示例。
% java Stylizer data/article3.xsl  data/article3.xml
  1. 现在运行程序,结果应该看起来像这样:
[...]
<h2>The <i>Third</i> Major Section</h2>
<p>In addition to the inline tag in the heading, this section  defines the term <i>inline</i>, which literally means "no line break". It also adds a simple link to the main page for the Java platform (<a href="http://java.sun.com">http://java.sun.com</a>),  as well as a link to the <a href="http://java.sun.com/xml">XML</a> page.</p>
  1. 干得好!你现在已经将一个相当复杂的 XML 文件转换为 HTML。(尽管一开始看起来很简单,但它确实提供了很多探索的机会)。

打印 HTML

您现在已将 XML 文件转换为 HTML。总有一天,会有人制作出一个了解 HTML 的打印引擎,您将能够通过 Java 打印服务 API 找到并使用它。到那时,您将能够通过生成 HTML 打印任意 XML 文件。您只需设置一个样式表并使用您的浏览器。

XSLT 还能做什么?

尽管本节内容很长,但只是触及了 XSLT 的能力表面。XSLT 规范中还有许多额外的可能性等待着您。以下是一些值得关注的事项:

import(第 2.6.2 节)和 include(第 2.6.1 节)

rt(第 2.6.2 节)和 include(第 2.6.1 节)使用这些语句对 XSLT 样式表进行模块化和组合。include 语句只是插入所包含文件中的任何定义。import 语句允许您用自己样式表中的定义覆盖导入文件中的定义。

for-each 循环(第 8 节)

遍历一系列项目并依次处理每个项目。

choose(case 语句)用于条件处理(第 9.2 节)

根据输入值分支到多个处理路径之一。

生成数字(第 7.7 节)

动态生成编号的章节、编号元素和数字文字。XSLT 提供三种编号模式:

  • Single:将项目编号在单个标题下,就像 HTML 中的有序列表
  • Multiple:生成多级编号,如"A.1.3"
  • Any:无论项目出现在何处,都连续编号,就像课程中的脚注。

格式化数字(第 12.3 节)

控制枚举格式,以便获得数字(format="1")、大写字母(format="A")、小写字母(format="a")或复合数字,如"A.1",以及适合特定国际区域设置的数字和货币金额。

排序输出(第 10 节)

按照所需的排序顺序生成输出。

基于模式的模板(第 5.7 节)

多次处理一个元素,每次在不同的“模式”中。您可以向模板添加一个模式属性,然后指定来仅应用具有匹配模式的模板。结合属性,将基于模式的处理应用于输入数据的子集。

变量(第 11 节)

变量类似于方法参数,可以控制模板的行为。但它们并不像你想象的那样有价值。变量的值仅在定义它的当前模板或标签(例如)的范围内才可知。你无法将一个值从一个模板传递到另一个模板,甚至无法将一个模板的封闭部分的值传递到同一模板的另一部分。

即使是“全局”变量,这些说法也是正确的。你可以在模板中更改它的值,但更改仅适用于该模板。当用于定义全局变量的表达式被评估时,该评估发生在结构的根节点的上下文中。换句话说,全局变量本质上是运行时常量。这些常量可以用于改变模板的行为,特别是与包含和导入语句结合使用时。但变量不是通用的数据管理机制。

变量的问题

创建一个单一模板并为链接的目标设置一个变量,而不是费力地设置一个带参数的模板并以两种不同的方式调用它,这是一个诱人的想法。这个想法是将变量设置为默认值(比如,LINK标签的文本),然后,如果目标属性存在,将目的地变量设置为目标属性的值。

如果这个方法行得通就好了。但问题在于变量只在定义它们的范围内才被知晓。因此,当你编写一个标签来改变变量的值时,该值只在标签的上下文中被知晓。一旦遇到,对变量设置的任何更改都会丢失。

一个同样诱人的想法是用一个变量()来替换text()|B|I|U|DEF|LINK规范。但由于变量的值取决于它的定义位置,全局内联变量的值由文本节点、`节点等组成,这些节点恰好存在于根级别。换句话说,在这种情况下,这样一个变量的值是空的。

相关文章
|
10天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(二十九)-java+ selenium自动化测试- Actions的相关操作上篇(详解教程)
【4月更文挑战第21天】本文介绍了Selenium中处理特殊测试场景的方法,如鼠标悬停。Selenium的Actions类提供了鼠标悬停功能,用于模拟用户在网页元素上的悬停行为。文中通过实例展示了如何使用Actions悬停并展开下拉菜单,以及在搜索时选择自动补全的字段。代码示例包括了打开百度首页,悬停在“更多”元素上显示下拉菜单并点击“音乐”,以及在搜索框输入关键词并自动补全的过程。
34 0
|
3天前
|
Java 测试技术 Python
《手把手教你》系列技巧篇(三十六)-java+ selenium自动化测试-单选和多选按钮操作-番外篇(详解教程)
【4月更文挑战第28天】本文简要介绍了自动化测试的实战应用,通过一个在线问卷调查(&lt;https://www.sojump.com/m/2792226.aspx/&gt;)为例,展示了如何遍历并点击问卷中的选项。测试思路包括找到单选和多选按钮的共性以定位元素,然后使用for循环进行点击操作。代码设计方面,提供了Java+Selenium的示例代码,通过WebDriver实现自动答题。运行代码后,可以看到控制台输出和浏览器的相应动作。文章最后做了简单的小结,强调了本次实践是对之前单选多选操作的巩固。
11 0
|
3天前
|
Java 测试技术 项目管理
Java基础教程(22)-构建工具Maven的基本使用
【4月更文挑战第22天】Maven是Java项目管理及构建工具,简化构建、测试、打包和部署等任务。遵循约定优于配置原则,核心是`pom.xml`配置文件,用于管理依赖和项目信息。安装涉及下载、解压、配置环境变量。在IDEA中使用Maven创建项目,通过`pom.xml`添加依赖和管理版本。常用命令包括`clean`、`compile`、`test`、`package`、`install`和`deploy`。IDEA支持直接执行这些命令。
|
3天前
|
NoSQL Java 关系型数据库
Java基础教程(21)-Java连接MongoDB
【4月更文挑战第21天】MongoDB是开源的NoSQL数据库,强调高性能和灵活性。Java应用通过MongoDB Java驱动与之交互,涉及MongoClient、MongoDatabase、MongoCollection和Document等组件。连接MongoDB的步骤包括:配置连接字符串、创建MongoClient、选择数据库和集合。伪代码示例展示了如何建立连接、插入和查询数据。
|
4天前
|
存储 前端开发 测试技术
《手把手教你》系列技巧篇(三十五)-java+ selenium自动化测试-单选和多选按钮操作-下篇(详解教程)
【4月更文挑战第27天】本文介绍了使用Java+Selenium进行Web自动化测试时,如何遍历和操作多选按钮的方法。文章分为两个部分,首先是一个本地HTML页面的示例,展示了多选按钮的HTML代码和页面效果,并详细解释了遍历多选按钮的思路:找到所有多选按钮的共同点,通过定位这些元素并放入list容器中,然后使用for循环遍历并操作。 第二部分介绍了在JQueryUI网站上的实战,给出了被测网址,展示了代码设计,同样使用了findElements()方法获取所有多选按钮并存储到list中,然后遍历并进行点击操作。最后,文章对整个过程进行了小结,并推荐了作者的其他自动化测试教程资源。
12 0
|
4天前
|
Java 关系型数据库 MySQL
Java基础教程(20)-Java连接mysql数据库CURD
【4月更文挑战第19天】MySQL是流行的关系型数据库管理系统,支持SQL语法。在IDEA中加载jar包到项目类路径:右击项目,选择“Open Module Settings”,添加库文件。使用JDBC连接MySQL,首先下载JDBC驱动,然后通过`Class.forName()`加载驱动,`DriverManager.getConnection()`建立连接。执行CRUD操作,例如创建表、插入数据和查询,使用`Statement`或`PreparedStatement`,并确保正确关闭数据库资源。
|
5天前
|
设计模式 算法 Java
Java基础教程(19)-设计模式简述
【4月更文挑战第19天】设计模式是软件设计中反复使用的代码设计经验,旨在提升代码的可重用性、可扩展性和可维护性。23种模式分为创建型、结构型和行为型三类。创建型模式如工厂方法、抽象工厂、建造者、原型和单例,关注对象创建与使用的分离。结构型模式涉及对象组合,如适配器、装饰器、外观等,增强结构灵活性。行为型模式专注于对象间职责分配和算法合作,包括责任链、命令、观察者等。设计模式提供标准化解决方案,促进代码交流和复用。
|
6天前
|
前端开发 测试技术 Python
《手把手教你》系列技巧篇(三十三)-java+ selenium自动化测试-单选和多选按钮操作-上篇(详解教程)
【4月更文挑战第25天】本文介绍了自动化测试中如何处理单选和多选按钮的操作,包括它们的定义、HTML代码示例以及如何判断和操作这些元素。文章通过一个简单的HTML页面展示了单选和多选框的示例,并提供了Java+Selenium实现的代码示例,演示了如何检查单选框是否选中以及如何进行全选操作。
12 0
|
6天前
|
网络协议 Java 网络架构
Java基础教程(18)-Java中的网络编程
【4月更文挑战第18天】Java网络编程简化了底层协议处理,利用Java标准库接口进行TCP/IP通信。TCP协议提供可靠传输,常用于HTTP、SMTP等协议;UDP协议则更高效但不保证可靠性。在TCP编程中,ServerSocket用于监听客户端连接,Socket实现双进程间通信。UDP编程中,DatagramSocket处理无连接的数据报文。HTTP编程可以通过HttpURLConnection发送请求并接收响应。
|
7天前
|
前端开发 Java 测试技术
《手把手教你》系列技巧篇(三十二)-java+ selenium自动化测试-select 下拉框(详解教程)
【4月更文挑战第24天】本文介绍了在自动化测试中处理HTML下拉选择(select)的方法。使用Selenium的Select类,可以通过index、value或visible text三种方式选择选项,并提供了相应的取消选择的方法。此外,文章还提供了一个示例HTML页面(select.html)和相关代码实战,演示了如何使用Selenium进行选择和取消选择操作。最后,文章提到了现代网页中类似下拉框的新设计,如12306网站的出发地选择,并给出了相应的代码示例,展示了如何定位并选择特定选项。
17 0