使用Java和XSLT的10条技巧

这篇文章从书中选出了我认为非常重要的10条技巧。但实际上这有限的10条只是粗略的描述了什么是可能的。其中大多数都集中在Java和XSLT的组合上,而不是在XSLT(可扩展样式表转换)技术规范。而更周详的信息,在文章结尾处指出了一些有价值的资源。
基本的XSL转换是非常简单的:一个或多个包含着指令的XSLT样式表,这些指令定义了怎么把XML数据转换成其他格式。XSLT处理器完成实际的工作;Sun微系统的Java API for XML Processing (JAXP)为不同种类的处理器提供了一套标准的Java接口。这里有一个用JAXP的API执行XSL转换的简单例子:
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
public class Transform {
/**
* Performs an XSLT transformation, sending the results
* to System.out.
*/
public static void main(String[] args) throws Exception {
if (args.length != 2) {
System.err.println("Usage: java Transform [xmlfile] [xsltfile]");
System.exit(1);
}
File xmlFile = new File(args[0]);
File xsltFile = new File(args[1]); // JAXP reads data using the Source interface
Source xmlSource = new StreamSource(xmlFile);
Source xsltSource = new StreamSource(xsltFile);
// the factory pattern supports different XSLT processors
TransformerFactory transFact = TransformerFactory.newInstance();
Transformer trans = transFact.newTransformer(xsltSource);
trans.transform(xmlSource, new StreamResult(System.out));
}
}
你能点击这里下载一个非常小的ZIP文件,这个文件包含了这个例子及相应的XSLT样式表和XML数据文件。其中的README文件解释了怎样编译和运行这个例子。
这个这个例子是利用StreamSource从文件中读取数据,JAXP还能从SAX解释器或DOM树来读取XML数据。下面依次介绍我推荐的10条技巧:

1、 尽可能使用缓存。
执行XSLT转换是非常耗费CPU和内存的,所以在所有时候进行可能的优化都是非常有意义的。使用由XSLT驱动的Web应用,提高他的实时运行性能表现的最佳方法之一就是使用各种类型的缓存技术。
图一举例说明了一个典型的使用XSL对数据库进行转换的Web应用。

图一、典型的XSL转换

和动态生成的XML不同,XSLT样式表是静态存储在文件中的。由于这些文件非常少被改动,就能用JAXP的javax.xml.transform.Templates接口把他们解析好了进内存里缓存起来。下面这个程式片断解释了这个过程是怎样完成的:
Source xsltSource = new StreamSource(xsltFile);
TransformerFactory transFact = TransformerFactory.newInstance();
Templates cachedXSLT = transFact.newTemplates(xsltSource);
Transformer trans = cachedXSLT.newTransformer();
当XSLT样式表通过Templates接口缓存进了内存中,目前他就能被重复用于非常多不同的转换里。最重要的好处是,这样就避免了重复把XSLT解析进内存。他也给了XSLT处理器一个机会来优化转换指令,就象编译器优化软件那样。
有人可能会想是否能把XML数据也缓存进内存中。对于那些高度动态和个体化的应用,XML数据是随着每一个客户请求而动态生成的并随时都在变化。对于这种应用,缓存是不实际的。对于非常多其他类型的应用,XML数据可能改动的不是非常频繁。当数据改动不是非常频繁时,相对于缓存XML数据,将转换后的结果缓存可能更有意义。这是一种最快的可行性解决方案,推荐在所有可行的情况下使用。

2、部署前做测试。
在研发Web应用项目选择XML和XSLT的关键在于能清晰的把数据、程式逻辑和表达分开。Java代码和后台数据源交互并生成XML数据,XSLT样式表把XML数据转换为XHTML(或WML,或其他),然后浏览器显示结果。
这种结构的一个独特的,然而时常被忽略的好处是他支持自动单元测试的能力。象JUnit这样的工具鼓励程式员去写适合自动单元测试的套件。这些测试大大的减少了在系统中加入新特性时所产生的错误。考虑一下一个典型的Java+XML+XSLT网站的这些组件:
用Java实现商业逻辑。由于Java代码没有和表达逻辑混在一起,就能象其他所有Java代码相同测试他。
把应用数据转换为XML。这一步是特别容易的。只要生成XML然后用一个DTD或一个XML Schema验证他就行了。
把XML转换为XHTML。同样的,生成的XHTML能用一个XHTML DTD来验证。虽然这样做不能证实信息是正确的,不过的确能确保XHTML被正确的生成而且是有效的。
和非常多其他的Web研发技术不同,测试这些单元中的所有一个都不用将其部署到Web服务器上。这使自动单元测试更容易被实现,自动单元测试也是极限编程(XP)技术的一个关键组成部分。

3、尽量让XSLT样式表简单。
至少有两个理由要保持XSLT样式表简单。第一,XSLT并不是个象Java那样丰富的编程语言。虽然XSLT擅于转换,不过在样式表中嵌入太多的应用逻辑会使他变得相当复杂。因为这个原因,就应该在创建XML之前用Java实现尽可能多的商业逻辑。然后再用XSLT转换XML就应该简单得多了。
第二个保持样式表简单的理由是XSLT的语法不容易被读懂。XML标签使XSLT非常容易解析和方便的做程式化的处理,但所有的那些XML标签也使得样式表不容易被读懂。有几个小技巧能帮助程式员更容易读懂和处理XSLT样式表:
使用具有语法区分功能的编辑器,如Altova的XML Spy。
为每一个XSLT模板添加有差别的注释。这样就有助于打破那种在大堆被括在’<’和’>’的字符串里搜索时的单调。
对最高层的变量和样式表参数采用一定的命名规则。
把通用的方法取出来放进第二个样式表中,用<xsl:import>来重用代码。
4、和XSLT一起使用CSS。
这条技巧是和上一条联系在一起的,他也能大大的减少XSLT样式表的复杂程度。
XSLT和CSS分别执行不同的任务并相互补充。XSLT把XML转换为其他的格式,如XHTML或WML,而CSS只是定义表达的样式。作为生成的XHTML的一部分,有时XSLT也能生成一些样式元素来使线条变模糊。
建议写一些独立的CSS文件,来代替在XSLT样式表中嵌入大量关于字体、颜色和其他的样式元素。XSL转换产生的XHTML只是包含这些独立的CSS文件。这就使XHTML更小,同时简化了XSLT,也使得浏览器下载页面时速度更快。
同样的技术也适用于JavaScript,应该存放一些独立的文件而不是把他们直接嵌入到转换中去。

5、小心处理不间断空格。
作者提示:作为对读者的回应,我已重写了这条技巧,加入了我最近学到的关于不间断空格的新知识。感谢广大读者的反馈。[编者提示:我们已在文件的尾部为附加评论加入了一个读者反馈链接。]
不间断空格对于XHTML来说是个非常有用的特性,他能阻止浏览器在文字中引入换行符。他同时使得强迫两个以上连续的空格成为可能;因为浏览器总是把普通的空格(和其他的白空格字符)序列处理成一个空格。这里是个包含不间断空格的XHTML的例子:
Aidan&nbsp;Burke
当人们创建XHTML网页时,他们通常是象上面显示的那样在他们的源文件中插入"&nbsp;"字符。所有的浏览器都会把这个字符序列翻译成一个不间断空格并正确显示。然而,当用XSLT生成XHTML时,处理的方法就不同了。
XSLT样式表必须是格式正确的XML。因为"&nbsp;"不是XML预先定义好的五个标签,他不能直接被包含在样式表中。比如,接下来的这个XSLT片就不管用:
<!-- won’t work... -->
<xsl:text>Aidan&nbsp;Burke</xsl:text>
这种特征使XSLT程式员必须用一种略微不同的方法来使用这种特性:
<xsl:text>Aidan Burke</xsl:text>
结果表明,所有的案例都工作得非常好。当样式表的输出方法是"html"时,像Xalan这样的处理器会自动的把字符实体" "转换为序列"&nbsp;"。从网络浏览器的角度来看,这看起来和其他的不间断空格没什么两样。
这里有一个完整的XSLT样式表的例子就是这样做的
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:text>Aidan Burke</xsl:text>
</xsl:template>
</xsl:stylesheet>
当用Xalan时,这个转换的输出看起来是这样的:
Aidan&nbsp;Burke
这非常好,因为浏览器知道怎么显示"&nbsp;"。但非常不幸,XSLT规范并没有需求XSLT处理器把" "转换为"&nbsp;"。你必须在遇见这个问题的所有时候,对你使用的XSLT处理器进行这项测试。
有些程式员不喜欢必须记住"160"代表不间断空格。所以他们在XSLT样式表的DTD子集中定义这样一个实体:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xsl:stylesheet [
<!ENTITY nbsp " ">
]>
<xsl:stylesheet version="1.0" ...
目前,能用"&nbsp;"来代替" "。因为XML解析器在XSLT处理"&nbsp;"之前就把这个实体转换成了" ",这也就方便了样式表的作者。提醒一句:有些XML相关的工具会在见到DOCTYPE时试着验证XSLT样式表。因为DTD子集没有包含所有XSLT元素的定义,验证就会报告错误。
如果流行的XSLT处理器会自动把" "转换为"&nbsp;",会有什么问题呢?问题就是,当样式表的输出是"xml"而不是"html"时就会出现错误。
当XSLT输出方法是"html"时,大多数XSLT处理器修改他们的输出并提供给网络浏览器。比如,象"<br />"这样的标签,是个有效的XML,可能会被转换为"<br>"。这更适用于在比较老的浏览器,但却不是格式正确的XML。
XHTML是目前被国际互连网联盟所推荐的用于书写网页的格式。因为XHTML文件必须是格式正确的XML,XSLT样式表作者非常可能希望在生成XHTML时用"xml"的输出格式而不是"html"。这是个生成XHTML的XSLT样式表的第一部分:
<?xml version="1.0" encoding="UTF-8"?>br>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
encoding="UTF-8"/>
<xsl:template match="/">
<html xmlns="http://www.w3.org/1999/xhtml">
...remainder omitted
当输出方法是"xml"时,Xalan不会把" "转换为"&nbsp;"。相反,他会在结果树中插入一个160的字符码。这在有些时候会引起问题。比如,图2是运行在视窗系统 2000上的IE 5.5浏览器的一张截图。注意在有趣的字母"A"上有一个符号:
下载这个例子试一下结果。
图2的下半部分显示了一个在大多数情况的都能正常工作的交换技术。下面介绍了他怎么工作:
<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>
disable-output-escaping="yes"使XSLT处理器在生成结果树时不再把"&nbsp;"转换为字符码160。相反,他将字符序列"&nbsp;"保留而不变化。这样浏览器就能正确的显示不间断空格。
我必须提醒你注意的是XSLT规范并没有需求XSLT处理器支持disable-output-escaping,所以所有人在使用这个技术之前,请先用特别的工具测试一下。

图2,用"xml"输出方法(上方)和用disable-output-escaping方法(下方)的结果对比

下面对上面提到的这些技术做个总结:
用" "字符实体来代表不间断空格。因为大多数的XSLT会把这个实体转换为字符序列"&nbsp;",所以当输出方法是"html"时,这是能正确工作的。XSLT规范并没有需求这样做,但Xalan这样做了。
定义一个"&nbsp;"实体并使用他。这和上一点有同样的效率,但对于样式表作者来说看起来更好一点。然而,某些工具也许会试图用不存在的DTD来验证样式表,这时可能会出现问题。
用<xsl:text disable-output-escaping="yes">&amp;nbsp;</xsl:text>作为" "的第二个选择。这在输出方法是"xml"时特别有用。XSLT规范并不需求处理器支持disable-output-escaping。
6、写XML生成器类。
为了应用XSL转换,就必须要把Java对象转换成一定的XML数据。这能用以下的几个途径来完成:
1) 为每个类增加一个getXML()方法。
2) 写一个知道怎么将特定对象转换为XML的XML生成器。
3) 用一个熟知的Java-to-XML API来自动的转换为XML。
第一种途径看起来可能象下面这样:
public class Customer {
public Element getXML(Document doc) {
// use the DOM API to create an Element
// representing this object
...
}
...
}
这种途径非常容易解释和理解,但却有一个关键的设计缺点。关键的问题在于特定的XML表示方法和每个类紧紧的绑在了一起。当需要一个新的XML表示时,就必须写新的方法。这意味着当加入越来越多的XML"视图"时,类也会越变越大。
不难想象这样的情况,就是希望对于一个对象有多于一个的XML表示。在一份显示有成百上千的客户概要报表中,只有每个客户的非常少几个关键字段出目前XML数据中。而在一个客户的周详报表中,XML数据应该包含关于这个客户的所有信息。
第二种途径把XML的生成代码分离出来放在几个工具类里。一个关于客户的XML生成器看起来可能象下面这样的:
public class CustomerDOMProducer {
public static Element toXML(Customer cust, Document doc) {
... use the DOM API to create a fragment of XML
}
}
简单的从Customer类中把XML生成代码去掉;要增加新的XML表达时就只是简单的写附加的XXXDomProducer类就行了。这样甚至可能改为用象JDOM这样的non-DOM APIs,也不必对Customer代码作所有改动了。
-----------------------------------------------------------------------------------------------------------------------
更多关于JDOM的信息,不要错过Brett McLaughlin最近发行的《Java&XML, 2ndEdition》。
-----------------------------------------------------------------------------------------------------------------------
第三种途径也值得提一下,是用一种产品把Java对象转换为XML。虽然这些类型的工具对于持续和和应用程式进行数据交换方面非常好,但他们在XSL转换方面可能不是非常最佳。这是因为生成的XML可能比手写代码方案提供的复杂得多,潜在的也就导致了更为复杂的XSLT样式表。

7、假设Cookie是被禁止的。
Servlet API支持用HttpSession来跟踪会话。这使象购物车那样的技术成为可能。这个类的默认行为是依靠浏览器的cookie来鉴别每个用户,不过用户能禁止cookie。
当浏览器的cookie被禁止时,我们的应用就必须依靠其他某种机制来鉴别用户。URL重写就是servlet API用到的这一技术。因为各种原因,URL重写并不是自动发生的。为了在cookie被禁止时支持会话跟踪,程式员必须记住对应用程式发出的每一个URL进行编码。这能靠给每一个超链接、表单动作、或重定向URL加上一个jsessionid=nnnnn来完成。下面的表列举了有和没有验证标记的URL:

普通URL 编码后的URL
<a href="mylink"> <a href="mylink;jsessionid=129j2fjs87l156">
<form action="mylink"> <form action="mylink;jsessionid=129j2fjs871156">

当用户点击一个编码的超链接或提交一个编码的表单时,servlet容器能通过检查jsessionid的值来确定他或她的身份。
在用XSLT生成XHTML时,由于验证标识是动态的而且每个用户的身份都不同,所以这个会话标识应该被嵌入到每一页中,他应该作为一个样式表的参数被传递。下面是怎样在每个XSLT样式表顶部定义这个参数的例子:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!--
*********************************************************
** global.sessionID : Used for URL-rewriting to implement
** session tracking without cookies.
*********************************************************
-->
<xsl:param name="global.sessionID"/>
...
在一个servlet端的应用程式中,Java代码用JAXP的Transformer类把这个会话标识传给XSLT处理器。他非常聪明,只在cookie不起作用的情况下才这样做:
protected void doGet( HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
Transformer trans = ... // obtain Transformer from JAXP
HttpSession session = req.getSession(true);
// allow cookieless session tracking
if (!req.isRequestedSessionIdFromCookie()) {
String sessionID = session.getId();
trans.setParameter("global.sessionID", ";jsessionid=" + sessionID);
}
回到XSLT端的应用程式中,这个global.sessionID参数能在生成每一页时被加到超链接和表单动作中。这个技术在《Java and XSLT》的第8章"Additional Techniques"中作了完整的讲解。

8、把XSLT作为一个代码生成器使用。
虽然XSLT通常是用来做基于Web的转换,但他并不是被局限于用作XHTML的输出。XSLT能将XML转换为任意的文本格式,这就使他成为非常多类型代码的生成器和其他研发工具的一个最佳的选择。
当用XSLT作为一个基本的代码生成器时,将他集中在重复的和高度结构化的应用上是最佳的。非常多跟EJB相关的应用是高度结构化和有点重复的,使的XSLT成为代码生成的一个最佳的选择。
-------------------------------------------------------------------------------------------------------------------------
期待O’Reilly的《Enterprise Java Beans》第三版,因为9月就会发行。
-------------------------------------------------------------------------------------------------------------------------

9、对于i18n用<xsl:import>
图3显示了怎样将XSLT样式表模块化来支持国际化:

图3、XSLT国际化

这是利用<xsl:import>特征的一个有趣的窍门。用<xsl:import>,一个样式表能导入一个或多个其他的样式表。如果样式表"A"导入样式表"B",样式表"A"中定义的模块和变量优先于在样式表"B"中找到的。
特定语言的样式表看起来可能是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:import href="common.xslt"/>

<xsl:variable name="lang.pageTitle">Welcome to XSLT!</xsl:variable>
</xsl:stylesheet>
通用的样式表可能是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8"/>

<xsl:template match="/">
<html>
<head>
<title><xsl:value-of select="$lang.pageTitle"/></title>
</head>
...etc
就象这里显示的相同,通用的样式表里不写给用户显示的具体文本(如页面标题)。相反,他依靠在特定语言的样式表中定义的变量。用这种方式,增加新的语言支持就只是创建一个新语言的样式表。
这非常类似于"ordinary Java"国际化,是用不同的属性文件定义语言相关的文本。

10、设立StreamSource来解析相关的URI。
看一看下面的JAXP代码(被强调的是有问题的部分):
// Stream containing XML data
InputStream xmlStream = ...
// Stream containing XSLT stylesheet
InputStream xsltStream = ...

Source xmlSource = new StreamSource(xmlStream);
Source xsltSource = new StreamSource(xsltStream);

TransformerFactory transFact =
TransformerFactory.newInstance();
Transformer trans = transFact.newTransformer(xsltSource);
trans.transform(xmlSource, new StreamResult(System.out));
目前假设这个XSLT样式表导入了另外一个样式表,如下所示:
<xsl:import href="formatName.xslt"/>
当XSLT处理器不知道到哪里去找formatName.xslt时就会引起问题。在XML数据中包含了对其他文件的引用时,同样的问题也会发生。这段代码能通过改动StreamSource对象的构造来解决:
Source xmlSource = new StreamSource(xmlStream, "file:///C:/data/xml/");
Source xsltSource = new StreamSource(xsltStream, "file:///C:/data/xslt/);
第二个参数提供了包含有XML和XSLT文件的URI。目前,当XSLT处理器解析XML数据和XSLT样式表中的URI引用时,就知道到哪里去寻找了。

更多知识
XSLT并不是一门非常难的语言,虽然他工作的方式和Java大不相同。埋头写样式表可能是克服初学时的困难的最佳方法。这里有一些关于XSLT的附加资源:

javaxslt_example.zip: 下载一个XSLT样式表、XML文件和简单的JAXP转换程式的例子。
The latest XSLT specification 国际互连网联盟的最新XSLT规范。
Sun’s Java API for XML Processing (JAXP) site: 为不同种类的XML解析器和XSLT处理器提供了一套标准的Java接口
Altova’s XML Spy: 一个支持XSL转换的XML编辑器。
The SAXON XSLT processor: 来自Michael Kay的XSLT处理器。
The Xalan XSLT processor: 来自Apache 组织的XSLT处理器。

  • 以上内容由 华夏名网 搜集整理,如转载请注明原文出处,并保留这一部分内容。

使用Java和XSLT的10条技巧 (转)相关推荐

  1. 成为优秀Java程序员的10大技巧

    来自:http://geek.csdn.net/news/detail/114500 Java程序员有许多应遵循的守则或最佳实践方式.本文概述了每个开发者最应该遵循的10条守则或戒律,如果不遵循它们, ...

  2. 一级计算机照片咋拍,如何拍出锐利照片?你需要掌握的10条技巧

    1镜头的影响 [PConline 技巧]相信不少朋友都有过这样的疑问,明明已经购入了一部像样的摄影设备,却无法拍摄出如大师作品般清晰锐利的相片.其实很多时候,是不够了解自己的器材,或者错误的拍摄方法所 ...

  3. php serialize和json_encode哪个更快_学习PHP的10个技巧

    在开始学习PHP之前,花一些时间计划学习语言的方法可能是明智的. 学习过PHP的专业开发人员已经花费了大量时间来学习他们的技术.要模拟它们,您将需要确保有动力去做,并且理想地能够快速有效地学习PHP. ...

  4. 让你的 Node.js 应用跑得更快的 10 个技巧

    Node.js 受益于它的事件驱动和异步的特征,已经很快了.但是,在现代网络中只是快是不行的.如果你打算用 Node.js 开发你的下一个Web 应用的话,那么你就应该无所不用其极,让你的应用更快,异 ...

  5. 16位调色板和32位调色板_整理色板和调色板的10个技巧

    知道自己有东西,但不知道它在哪里会令人沮丧. 对于您为设计项目创建或保存的颜色,尤其如此. 不得不遍历色样 , 浪费时间 ,只好在需要切换色相时重新开始搜索. 如果您经常使用吸管工具或将CMYK值插入 ...

  6. Java性能优化最易操作的10大技巧!

    编辑 | ShirleyZ 译文 | 班纳睿 .一叶障目  .learner 原文 | https://coyee.com/article/11753-top-10-easy-performance- ...

  7. Eclipse调试Java的10个技巧【转】

    clipse调试Java的10个技巧 先提三点 不要使用System.out.println作为调试工具 启用所有组件的详细的日志记录级别 使用一个日志分析器来阅读日志 1.条件断点 想象一下我们平时 ...

  8. java看log技巧_Log日志框架的学习五.正确使用日志的10个技巧

    做一个苦逼的Java攻城师, 我们除了关心系统的架构这种high level的问题, 还需要了解一些语言的陷阱, 异常的处理, 以及日志的输出, 这些"鸡毛蒜皮"的细节. 这篇文章 ...

  9. sql 非主键每年自增_或许你不知道的 10 条 SQL 技巧

    上文我们简述了 SQL 的一些进阶技巧,一些朋友觉得不过瘾,我们继续来下篇,再送你 10 个技巧 一. 使用延迟查询优化 limit [offset], [rows] 经常出现类似以下的 SQL 语句 ...

最新文章

  1. Github远程推送一直Everything up-to-date
  2. python科学计算笔记(一)NumPy中ndarray对象、ufunc运算、矩阵运算
  3. 【转】ASCII码表
  4. hive的安装和升级
  5. 做三维模型_这几款倾斜实景三维裸眼3D采集软件你了解吗?
  6. C++builder Tokyo 调用com 不正确的变量类型
  7. CNN提取文本特征,融合PMF模型实现推荐系统
  8. MCGS7.7嵌入版软件安装方法
  9. python ffmpeg mp3文件转为wav文件
  10. Cloudera Manager 理论
  11. 浏览器插件——轻松、快速下载网站源代码
  12. VMware Workstation虚拟机安装及虚拟机搭建(内有虚拟机安装包及序列号和系统镜像)...
  13. finecms相关信息-随时更新
  14. 单片机篮球记分牌c语言程序和实训报告,单片机实现篮球记分牌的设计
  15. 辽宁移动_E900V21E_S905L3_线刷固件包
  16. AI新动向:多模态+自监督!Meta AI一次搞定语音、视觉和文本三个SOTA
  17. 共模电感(扼流圈) 差模电感(扼流圈)
  18. 520表白攻略 程序员必要的相亲准备 最近你相亲表白了嘛
  19. 无代码四月资讯|元宇宙、AI与无代码的精彩碰撞...
  20. 详解上海交大819考研

热门文章

  1. 我用Java写的象棋外挂成功了
  2. 企业级Web应用用户界面设计杂谈[转]
  3. linux时间跳变影响,Linux起用夏令时,跳变后导致容器日志时间和系统时间相差一小时...
  4. DoozyUI⭐️一、什么是DoozyUI
  5. 回家感言一(火车上解决bug的你)
  6. 北交计算机学硕培养计划,北京交通大学_研究生培养计划表.doc
  7. 中国移动苏杭研发中心---android应用开发
  8. 戴琼海院士:国际经济形势下滑,为何全球却在大力发展人工智能?
  9. absolute和relative定位总结(水平居中和垂直居中)
  10. opengl 三线性和各项异性过滤