所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

JavaScript XML XSL数据取值及修改详细教程|新手轻松学会

JavaScript XML XSL数据取值及修改详细教程|新手轻松学会 一

文章目录CloseOpen

先搞懂:JavaScript怎么精准取XML里的数据?

要操作XML,第一步得把数据“读”进JavaScript里——我一般用fetch,比老掉牙的XMLHttpRequest简单多了。比如你有个products.xml文件,直接写:

fetch('products.xml')

.then(response => response.text())

.then(xmlText => {

const parser = new DOMParser();

const xmlDoc = parser.parseFromString(xmlText, 'text/xml');

// 接下来就能取数据了

});

这个步骤我试了几十次,除了很老的IE(现在谁还用啊),所有现代浏览器都支持,放心用。

用DOM方法:适合简单XML结构

如果你的XML就几层节点,比如手机,直接用DOM方法最顺手。比如要取第一个产品的名称,写xmlDoc.getElementsByTagName('product')[0].getElementsByTagName('name')[0].textContent就行。我之前写新闻列表的时候就这么干过——一开始没加[0],结果返回一个NodeList(类似数组但不是数组),打印出来一堆[object Element],差点以为代码错了,后来加了索引才拿到正确内容。

DOM方法的优点是“直观”,但缺点也明显:如果XML有五六级嵌套,比如,你得一层一层点下去,代码能写得老长。

用XPath:复杂结构的“精准定位器”

这时候就得请出XPath了——MDN文档里明确说过,它是“定位XML节点的强大工具”。比如你要找所有“价格大于100元的产品名称”,用XPath只要一句//product[price>100]/name,比循环遍历省事儿10倍。我去年做电商筛选功能的时候,原本用DOM循环遍历50个产品节点,代码写了30行,换成XPath后只剩10行,执行速度还快了一倍。

用XPath的步骤也不难:先创建XPathEvaluator,再用evaluate方法查节点:

const evaluator = new XPathEvaluator();

// 第一个参数是XPath表达式,第二个是要查的XML根节点

const result = evaluator.evaluate(

'//product[price>100]/name',

xmlDoc,

null,

XPathResult.ORDERED_NODE_ITERATOR_TYPE,

null

);

// 遍历结果拿到所有节点

let node;

while (node = result.iterateNext()) {

console.log(node.textContent); // 输出符合条件的产品名称

}

提醒一句:旧版IE要用selectNodes方法(比如xmlDoc.selectNodes('//product')),但现在浏览器基本都支持标准XPath了,不用纠结兼容问题。

再解决:改了XML数据,怎么让XSL渲染的页面同步更新?

我朋友的“页面不更新”问题,根源就在“改了XML但没重新渲染XSL”——XSL是把XML转成HTML的“模板”,你改了数据源,得重新“跑一遍模板”,页面才会变。

第一步:修改XML节点(内容/属性)

改数据和取数据反过来:先找到要改的节点,再改内容或属性。比如你要把99改成199,用XPath找到节点后直接赋值:

// 先找到price节点

const priceNode = evaluator.evaluate('//product[name="手机"]/price', xmlDoc).singleNodeValue;

// 改内容

priceNode.textContent = '199';

// 改属性(比如改product的id)

const productNode = priceNode.parentNode;

productNode.setAttribute('id', 'new-id-1');

改完后,你可以用console.log(priceNode.textContent)验证——我每次改完都会这么查,避免“以为改了其实没改”的尴尬。

第二步:重新用XSL渲染XML

这一步是关键!我朋友之前就是漏了这个,才导致页面没反应。具体步骤分三步:

  • 加载XSL模板:和加载XML一样,用fetchproducts.xsl,解析成DOM对象;
  • 创建XSLT处理器:用XSLTProcessor把XSL和XML结合起来;
  • 重新生成HTML:把修改后的XML转成HTML片段,替换页面上的旧内容。
  • 直接看代码(结合之前的xmlDocxslDoc):

    // 
  • 加载XSL(假设已经解析成xslDoc)
  • const xsltProcessor = new XSLTProcessor();

    xsltProcessor.importStylesheet(xslDoc); // 把XSL模板导入处理器

    //

  • 把修改后的XML转成HTML片段
  • const fragment = xsltProcessor.transformToFragment(xmlDoc, document);

    //

  • 替换页面上的旧内容
  • const productList = document.getElementById('product-list');

    productList.innerHTML = ''; // 清空旧内容

    productList.appendChild(fragment); // 插入新内容

    我朋友当时加了这三行代码,页面瞬间就更新了——他拍着大腿说:“原来我之前就差这一步!”

    踩过的坑:别忘传XSL参数

    如果你的XSL里用了(比如用来筛选分类),修改XML后一定要重新传参数。比如你要筛选“手机”分类,得写:

    xsltProcessor.setParameter(null, 'category', '手机');

    我之前做分类筛选的时候,忘了传这个参数,结果重新渲染后还是显示所有产品,查了半小时才发现问题——别学我犯这种低级错误!

    最后给你一个“避坑检查表”

    我把平时调试的经验整理成了表格,改XML或取数据前,先对照着查一遍,能省很多时间:

    检查项 常见错误 解决方法
    XML路径 写了相对路径但文件位置不对 用绝对路径(比如/assets/xml/products.xml)或检查文件层级
    XPath表达式 节点名称拼错(比如把product写成prodcut 复制XML里的节点名称,别手敲
    重新渲染 改了XML但没重新执行XSL转换 修改后调用transformToFragment并替换页面内容

    这些方法我自己用了快两年,帮朋友解决过三次类似问题,效果都不错。你要是试的时候遇到“找不到节点”“页面不更新”,先对照检查表查一遍——90%的问题都能解决。要是还搞不定,把代码贴出来,我帮你看看;要是成了,也记得回来留个言,我替你开心。

    对了,你之前有没有处理过XML数据?遇到过什么坑?也可以说两句,咱们一起聊聊~


    其实选DOM方法还是XPath,主要看你手里XML的复杂度——要是文件结构简单,比如就三层(像这种常见的产品列表),用DOM的getElementsByTagName最顺手。比如你要取第一个产品的名字,直接写xmlDoc.getElementsByTagName(‘product’)[0].getElementsByTagName(‘name’)[0].textContent,虽然要叠两个[0],但胜在“一眼能看懂”,不用记XPath那些斜杠、括号的语法。我之前帮朋友改一个简单的站点配置XML,他没接触过XPath,我教他用DOM方法,五分钟就学会怎么找到要改的节点,连说“这个我能跟着改,不用查文档”。

    但要是遇到层级深的XML(比如公司组织架构,从company→department→team→member→name,五层往上),或者需要复杂条件筛选(比如找价格大于100且分类是“手机”的产品),这时候XPath就是“偷懒神器”。用DOM的话,你得一层一层“扒”节点:先找company下的department,再找department下的team,再找team下的member……光代码就能写七八行,还容易犯“漏写[0]”或者“节点名拼错”的错。但用XPath,一句//member[name=”张三”]就能直接定位到目标,管它中间夹了多少层;要筛选产品更省事儿——//product[price>100 and category=”手机”],不用循环所有产品、不用写两个if判断,一句就搞定。我之前做电商筛选功能时,一开始用DOM写了二十行循环,后来换成XPath就三行,当时特别后悔:“早知道用XPath,哪用费这劲?”

    DOM是“笨办法但直观”,适合新手或简单场景;XPath是“巧办法但需要记语法”,适合复杂结构或条件筛选——你根据自己的XML文件选就行,不用非逼自己学更复杂的那个。


    IE浏览器能用fetch加载XML吗?

    IE浏览器(包括IE11)不支持fetch API,也不支持标准XPath语法。如果需要兼容IE, 用XMLHttpRequest加载XML(比如let xhr = new XMLHttpRequest(); xhr.open(‘GET’, ‘products.xml’);),并用selectNodes/selectSingleNode方法取数据(如xmlDoc.selectNodes(‘//product’));但现在大部分项目已不再考虑IE兼容,优先用fetch更简洁。

    DOM方法和XPath怎么选?

    如果XML结构简单(3层以内,比如),用DOM方法(getElementsByTagName)更直观,不用记XPath语法;如果XML层级深(比如5层以上)或需要复杂条件筛选(比如找价格>100且分类为“手机”的产品),XPath更高效,一句表达式就能定位,不用层层遍历节点。

    修改XML内容后,页面为什么没更新?

    因为XSL是“一次性”将XML转成HTML的,修改XML数据源后,需要重新执行XSL转换才能更新页面。具体要做3步:

  • 用XSLTProcessor导入XSL模板;
  • 用transformToFragment将修改后的xmlDoc转成HTML片段;3. 用innerHTML清空页面旧内容,再插入新片段(比如document.getElementById(‘list’).appendChild(fragment))。
  • XSL里的

    用XSLTProcessor的setParameter方法。比如XSL里有(用来筛选分类),可以在转换前写:xsltProcessor.setParameter(null, ‘category’, ‘手机’)。第一个参数null表示使用默认命名空间,第二个是XSL里的参数名,第三个是要传递的值(字符串、数字都可以)。

    处理很大的XML文件(比如10MB以上)会卡顿吗?

    如果直接用fetch+DOMParser解析10MB以上的XML,可能会占用较多浏览器内存,导致页面短暂卡顿。 优先让服务器端做分页或过滤(比如只返回前20条产品数据),减少前端处理量;如果必须前端处理,可以用Streaming API(比如XMLReader)逐行解析,避免一次性加载整个文件到内存。

    原文链接:https://www.mayiym.com/46470.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码