4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Reactでxmlファイルをアップロードして使う

Last updated at Posted at 2021-01-08

use-file-uploadを使ってXMLファイルをアップロードしてパースする手順のメモです

use-file-upload

今回はuse-file-uploadを使用しました
https://www.npmjs.com/package/use-file-upload

use-file-uploadはReactフックとして動作するライブラリで、useFileUpload()でstateを作っておいて、buttonなどからonclickで呼ぶ事でアップロードしたファイルをstateとして扱えるようにしてくれます。

以下の例のsource, name, size, fileはそれぞれblob url, ファイル名、ファイルサイズ、ファイルオブジェクトになります。画像ファイルをアップロードして表示する場合は、blob urlであるsourceをimgタグのsrcに与える事でサーバー上のファイルと同様に表示できます。

src/app.js
import React from 'react'
import { useFileUpload } from 'use-file-upload'
 
const App = () => {
  const [file, selectFile] = useFileUpload()
 
  return (
    <div>
      <button
        onClick={() => {
          // Single File Upload
          selectFile({}, ({ source, name, size, file }) => {
            // file - is the raw File Object
            console.log({ source, name, size, file })
            // Todo: Upload to cloud.
          })
        }}
      >
        Click to Upload
      </button>
 
      {file ? (
        <div>
          <img src={file.source} alt='preview' />
          <span> Name: {file.name} </span>
          <span> Size: {file.size} </span>
        </div>
      ) : (
        <span>No file selected</span>
      )}
    </div>
  )
}
 
export default App;

上記の例ではbuttonタグにCSSを設定せずに表示するので以下のようなシンプルなボタンが表示されます
image.png

アップロードしたXMLファイルをオブジェクトに変換

fileオブジェクトを直接触るやり方が分からなかったので、blob urlをXMLHttpRequestで読んでくるやり方でやりました。XMLHttpRequestでblobを読みに行ってresponseXMLでXMLとして取得します。XMLとして読めなかった場合はresponseXMLにnullが入りますので、nullでなかった場合は表示するというようにしました。

import React from 'react'
import { useFileUpload } from 'use-file-upload'

function applyGPX(xml){
  console.log(xml);
};

function getXML(source) {
  console.log('source:');
  console.log(source);

  var xhr = new XMLHttpRequest();
  xhr.onload = function(e){
    const xml = xhr.responseXML;
    if (xml != null){
      applyGPX(xml);
    } else {
      console.log('not xml file');
    }
  };
  xhr.open("GET", source);
  xhr.send();
};
 
const App = () => {
  const [file, selectFile] = useFileUpload()
 
  return (
    <div>
      <button
        onClick={() => {
          selectFile({}, ({ source, name, size, file }) => {
            getXML(source);
          })
        }}
      >
        Click to Upload
      </button>
 
      {file ? (
        <div>
          <span> Name: {file.name} </span>
          <span> Size: {file.size} </span>
        </div>
      ) : (
        <span>No file selected</span>
      )}
    </div>
  )
};
 
export default App;

xmlオブジェクトからほしい情報を拾う

XMLオブジェクトが作れたのでほしい情報を拾っていこうと思います。XMLHttpRequest.responseXMLで取得したオブジェクトはgetElementsByTagName(), getElementById(), getElementsByClassName()などで取得できます。

tag名で探す
const elements = hoge.getElementsByTagName('fuga')
ID名で探す
const elements = hoge.getElementById('fuga')
class名で探す
const elements = hoge.getElementsByClassName('fuga')

また、取得したelementのattributeは以下のように取得できます

attributeの取得
const attribute = elements[0].getAttribute('foo')

今回はgpxファイルを読み込むので以下のようにして緯度、経度、高度を取得しました。


function getTracks(xml){
  console.log('getTracks');
  const trackTags = xml.getElementsByTagName('trkpt');
  console.log('track length: ' + trackTags.length);

  var tracks = [];
  var elevations = [];
  for(let k = 0; k < trackTags.length; k++) {
    let element = trackTags[k];
    let latitude = parseFloat(element.getAttribute('lat'));
    let longitude = parseFloat(element.getAttribute('lon'));
    tracks.push([latitude, longitude]);

    let element2 = element.getElementsByTagName('ele')[0]
    let elevation = parseFloat(element2.innerHTML)
    elevations.push(elevation);
  };
  console.log([tracks, elevations]);
  return [tracks, elevations]

余談

use-file-upload以外にもいくつかReact用のアップロードライブラリを試したんですが、blobぐらい分かるよね?的なノリで書いてあって地味に苦戦しました。ウェブ関係のライブラリ制作者が常識だから省いても良いと思っている部分を勉強できる本があったら読みたいので、ご存知の方がいらっしゃいましたら教えて下さい。

4
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?