在Node.js中读取XML文件

时间:2015-09-30 18:19:57

标签: javascript xml node.js

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

sitemap.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>

我正在尝试在我的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));
    }
});

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

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

我错过了什么?

10 个答案:

答案 0 :(得分:18)

使用xml2json

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

&#13;
&#13;
fs = require('fs');
var parser = require('xml2json');

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

答案 1 :(得分:10)

来自the documentation

  

回调传递两个参数(错误,数据),其中数据是   文件的内容。

     

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

     

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

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

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

答案 2 :(得分:2)

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

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

如果你知道编码只是使用:

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

答案 3 :(得分:1)

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

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 ...



});

示例:

   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>"

答案 4 :(得分:1)

你可以试试这个

npm install express-xml-bodyparser --save

在客户端: -

 $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;
       });
   };
服务器端的

: -

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);
});

答案 5 :(得分:1)

对于快速服务器:

  app.get('/api/rss/', (_request: Request, response: Response) => {
    const rssFile = fs.readFileSync(__dirname + '/rssFeeds/guardian.xml', { encoding: 'utf8' })

    console.log('FILE', rssFile)

    response.set('Content-Type', 'text/xml')
    response.send(rssFile)
  })
  • 接受请求
  • 读取文件
  • 设置xml标题
  • 返回文件

答案 6 :(得分:0)

为了read an XML file in Node,我喜欢XML2JS package。这个包让我可以轻松地使用JavaScript中的XML。

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

答案 7 :(得分:0)

迟到这个帖子,只是在这里添加一个简单的提示, 如果您打算在js中使用已解析的数据或将其保存为json文件,请务必将explicitArray设置为false。输出将更友好

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

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

答案 8 :(得分:0)

@Sandburg在评论中提到xml-js,这个对我来说效果最好(在问了这个问题后的几年)。 xml2json需要一些我不想处理的Windows SDK,并且xml2js没有提供足够简单的OTB方法来搜索属性。

我不得不在3个节点深的xml文件中提取特定属性,xml-js轻松做到了。

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

带有以下示例文件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>

我使用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 as a json object
const jsonData = JSON.parse(convert.xml2json(xmlFile, {compact: true, spaces: 2}));

// find the node with my required attribute value
const targetNode = jsonData.stats.runs.latest.find(x => x._attributes.date === '2019-12-12');

console.log(targetNode._attributes.fail);  // outputs: 2

答案 9 :(得分:0)

步骤1 npm install xml2js --save

const xml2js = require('xml2js');
const fs = require('fs');
const parser = new xml2js.Parser({ attrkey: "ATTR" });

// this example reads the file synchronously
// you can read it asynchronously also
let xml_string = fs.readFileSync("data.xml", "utf8");

 parser.parseString(xml_string, function(error, result) {
   if(error === null) {
      console.log(result);
  }
  else {
    console.log(error);
  }

});