Javascript 在 Node.js 中读取 XML 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32873100/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 14:18:20  来源:igfitidea点击:

Reading XML file in Node.js

javascriptxmlnode.js

提问by user70192

I'm learning how to use Node. At this time, I have an XML file that looks like this:

我正在学习如何使用 Node.js。此时,我有一个如下所示的 XML 文件:

sitemap.xml

站点地图.xml

<?xml version="1.0" encoding="utf-8"?>

<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
  <url>
    <loc>http://www.example.com</loc>
    <lastmod>2015-10-01</lastmod>
    <changefreq>monthly</changefreq>
  </url>

  <url>
    <loc>http://www.example.com/about</loc>
    <lastmod>2015-10-01</lastmod>
    <changefreq>never</changefreq>
  </url>

  <url>
    <loc>http://www.example.com/articles/tips-and-tricks</loc>
    <lastmod>2015-10-01</lastmod>
    <changefreq>never</changefreq>
    <article:title>Tips and Tricks</blog:title>
    <article:description>Learn some of the tips-and-tricks of the trade</article:description>
  </url>
</urlset>

I am trying to load this XML in my Node app. When loaded, I want to only get the urlelements that include the use of the <article:elements. At this time, I'm stuck though. Right now, I'm using XML2JSvia the following:

我正在尝试在我的 Node 应用程序中加载这个 XML。加载时,我只想获取url包含使用<article:元素的元素。在这个时候,我被卡住了。现在,我通过以下方式使用XML2JS

var parser = new xml2js.Parser();
fs.readFile(__dirname + '/../public/sitemap.xml', function(err, data) {
    if (!err) {
        console.log(JSON.stringify(data));
    }
});

When the console.logstatement is executed, I just see a bunch of numbers in the console window. Something like this:

console.log语句执行时,我只是在控制台窗口中看到一堆数字。像这样的东西:

{"type":"Buffer","data":[60,63,120, ...]}

What am I missing?

我错过了什么?

回答by Sajith Mantharath

use xml2json

使用 xml2json

https://www.npmjs.com/package/xml2json

https://www.npmjs.com/package/xml2json

fs = require('fs');
var parser = require('xml2json');

fs.readFile( './data.xml', function(err, data) {
    var json = parser.toJson(data);
    console.log("to json ->", json);
 });

回答by Quentin

From the documentation.

文档中

The callback is passed two arguments (err, data), where data is the contents of the file.

If no encoding is specified, then the raw buffer is returned.

If options is a string, then it specifies the encoding. Example:

fs.readFile('/etc/passwd', 'utf8', callback);

回调传递了两个参数 (err, data),其中 data 是文件的内容。

如果未指定编码,则返回原始缓冲区。

如果 options 是字符串,则它指定编码。例子:

fs.readFile('/etc/passwd', 'utf8', callback);

You didn't specify an encoding, so you get the raw buffer.

您没有指定编码,因此您获得了原始缓冲区。

回答by chrisbyte

@Sandburg mentioned xml-jsin a comment and it worked best for me (several years after this question was asked). The others I tried were: xml2jsonwhich required some Windows Sdk that I did not want to deal with, and xml2jsthat did not provide an easy enough OTB way to search through attributes.

@Sandburgxml-js在评论中提到,它对我来说效果最好(在提出这个问题几年后)。我尝试过的其他方法是:xml2json它需要一些我不想处理的 Windows Sdk,并且xml2js没有提供足够简单的 OTB 方法来搜索属性。

I had to pull out a specific attribute in an xml file 3 nodes deep and xml-jsdid it with ease.

我不得不在 3 个节点深的 xml 文件中提取特定属性xml-js并轻松完成。

https://www.npmjs.com/package/xml-js

https://www.npmjs.com/package/xml-js

With the following example file stats.xml

使用以下示例文件 stats.xml

<stats>
  <runs>
    <latest date="2019-12-12" success="100" fail="2" />
    <latest date="2019-12-11" success="99" fail="3" />
    <latest date="2019-12-10" success="102" fail="0" />
    <latest date="2019-12-09" success="102" fail="0" />
  </runs>
</stats>

I used xml-jsto find the element /stats/runs/latestwith attribute @date='2019-12-12'like so

我曾经xml-js找到元素/stats/runs/latest与属性,@date='2019-12-12'像这样

const convert = require('xml-js');
const fs = require('fs');

// read file
const xmlFile = fs.readFileSync('stats.xml', 'utf8');

// parse xml file as a json object
const jsonData = JSON.parse(convert.xml2json(xmlFile, {compact: true, spaces: 2}));

const targetNode = 

    // element '/stats/runs/latest'
    jsonData.stats.runs.latest

    .find(x => 

        // attribute '@date'
        x._attributes.date === '2019-12-12'
    );

// targetNode has the 'latest' node we want
// now output the 'fail' attribute from that node
console.log(targetNode._attributes.fail);  // outputs: 2

回答by Atul Kr Dey

You can try this

你可以试试这个

npm install express-xml-bodyparser --save

at Client side:-

在客户端:-

 $scope.getResp = function(){
     var posting = $http({
           method: 'POST',
           dataType: 'XML',
           url: '/getResp/'+$scope.user.BindData,//other bind variable
           data: $scope.project.XmlData,//xmlData passed by user
           headers: {
              "Content-Type" :'application/xml'
            },
           processData: true
           });
       posting.success(function(response){
       $scope.resp1 =  response;
       });
   };

on Server side:-

在服务器端:-

xmlparser = require('express-xml-bodyparser');
app.use(xmlparser());
app.post('/getResp/:BindData', function(req, res,next){
  var tid=req.params.BindData;
  var reqs=req.rawBody;
  console.log('Your XML '+reqs);
});

回答by Nate

fs.readFile has an optional second parameter: encoding. If you do not include this parameter it will automatically return you a Buffer object.

fs.readFile 有一个可选的第二个参数:编码。如果您不包含此参数,它将自动返回一个 Buffer 对象。

https://nodejs.org/api/fs.html#fs_fs_readfile_filename_options_callback

https://nodejs.org/api/fs.html#fs_fs_readfile_filename_options_callback

If you know the encoding just use:

如果您知道编码,请使用:

fs.readFile(__dirname + '/../public/sitemap.xml', 'utf8', function(err, data) {
    if (!err) {
        console.log(data);
    }
});

回答by Daphoque

You can also use regex before parsing to remove elements not matching your conditions :

您还可以在解析之前使用正则表达式删除与您的条件不匹配的元素:

var parser = new xml2js.Parser();
fs.readFile(__dirname + '/../public/sitemap.xml', "utf8",function(err, data) {
    // handle err...

    var re = new RegExp("<url>(?:(?!<article)[\s\S])*</url>", "gmi")
    data = data.replace(re, ""); // remove node not containing article node
    console.log(data);
    //... parse data ...



});

Example :

例子 :

   var str = "<data><url><hello>abc</hello><moto>abc</moto></url><url><hello>bcd</hello></url><url><hello>efd</hello><moto>poi</moto></url></data>";
   var re = new RegExp("<url>(?:(?!<moto>)[\s\S])*</url>", "gmi")
   str = str.replace(re, "")

   // "<data><url><hello>abc</hello><moto>abc</moto></url><url><hello>efd</hello><moto>poi</moto></url></data>"

回答by Chad Campbell

In order to read an XML file in Node, I like the XML2JS package. This package lets me easily work with the XML in JavaScript then.

为了在 Node 中读取 XML 文件,我喜欢XML2JS 包。这个包让我可以轻松地在 JavaScript 中使用 XML。

var parser = new xml2js.Parser();       
parser.parseString(fileData.substring(0, fileData.length), function (err, result) {
  var json = JSON.stringify(result);
});

回答by KuN

coming late to this thread, just to add one simple tip here, if you plan to use parsed data in js or save it as json file, be sure to set explicitArrayto false. The output will be more js-friendly

这个帖子来晚了,在这里补充一个简单的提示,如果你打算在js中使用解析的数据或将其保存为json文件,请务必设置explicitArrayfalse. 输出将更加 js 友好

so it will look like,
letparser=newxml2js.Parser({explicitArray:false})

所以它看起来像,
letparser=newxml2js.Parser({explicitArray:false})

Ref: https://github.com/Leonidas-from-XIV/node-xml2js

参考:https: //github.com/Leonidas-from-XIV/node-xml2js