質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

解決済

1回答

2377閲覧

XMLの入れ子の重複タグの削除方法

tkshp

総合スコア174

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

0クリップ

投稿2021/07/16 18:19

編集2021/07/18 11:05

前提・実現したいこと

以下のようなXMLをJavaScriptで取得した場合、

JavaScript

1 <var xml = `<?xml version="1.0" encoding="UTF-8"?> 2 <city> 3 <shops> 4 <shop> 5 <id>1</id> 6 <name>shopA</name> 7 </shop> 8 </shops> 9 <shops> 10 <shop> 11 <id>2</id> 12 <name>shopB</name> 13 </shop> 14 </shops> 15 <shops> 16 <shop> 17 <id>3</id> 18 <name>shopA</name> 19 </shop> 20 </shops> 21 </city>

nameタグの値が重複しているタグをshops単位で削除して一意にして、以下のようにしたいのですが、
どのようなコードを組めばよいでしょうか?
ちなみにshopsはルートに1つ置くのではなく、コードに提示しているようにshop単位で置かれる仕様で考えています。
今回のXMLでは、shopA,shopB,shopAの3つしか存在しませんが、実際は任意にshops単位でshopがあるものを想定しています。

JavaScript

1 <var xml = `<?xml version="1.0" encoding="UTF-8"?> 2 <city> 3 <shops> 4 <shop> 5 <id>1</id> 6 <name>shopA</name> 7 </shop> 8 </shops> 9 <shops> 10 <shop> 11 <id>2</id> 12 <name>shopB</name> 13 </shop> 14 </shops> 15 </city>

また、今回の例ではidが1のほうのshopAを残しましたが、idが1のほうが消えて、idが3のほうのshopAが残る処理でも大丈夫です。

ご教示お願い致します。

試したこと

XMLの取得においては、jQueryを導入したほうが簡単に扱えそうだったので、jQueryを使ってXMLを処理することに決めました。
基本的なXMLの取得までの処理はわかりました。

・test.html

JavaScript

1 <script src="http://code.jquery.com/jquery.min.js"></script> 2 <script> 3 <var xml = `<?xml version="1.0" encoding="UTF-8"?> 4 <city> 5 <shops> 6 <shop> 7 <id>1</id> 8 <name>shopA</name> 9 </shop> 10 </shops> 11 <shops> 12 <shop> 13 <id>2</id> 14 <name>shopB</name> 15 </shop> 16 </shops> 17 <shops> 18 <shop> 19 <id>3</id> 20 <name>shopA</name> 21 </shop> 22 </shops> 23 </city>`; 24 25 var xmlDoc = $.parseXML(xml); 26 var city = $(xmlDoc).children("city") 27 <script>

デバッグ方法は、上記htmlファイルをChromeのログで見ているだけです。
console.logで結果を確認します。

shops単位でループさせて、重複をチェックと考えましたが、

var xmlDoc = $.parseXML(xml); $(xmlDoc).children("city").children("shops").each(function(){ console.log($(this).html()); });

XMLによっては、以下のように同名のshopsが3回以上出現する場合もありうることに気づき、
どういった処理にしたらよいか見当がつかない状態です。
ループで回すというよりも、C#のLinqのDistinctメソッドのようなものがJavaScript、もしくはjQueryに存在すれば、
それを使うという処理になるのでしょうか?

JavaScript

1 <var xml = `<?xml version="1.0" encoding="UTF-8"?> 2 <city> 3 <shops> 4 <shop> 5 <id>1</id> 6 <name>shopA</name> 7 </shop> 8 </shops> 9 <shops> 10 <shop> 11 <id>2</id> 12 <name>shopB</name> 13 </shop> 14 </shops> 15 <shops> 16 <shop> 17 <id>3</id> 18 <name>shopA</name> 19 </shop> 20 </shops> 21 <shops> 22 <shop> 23 <id>4</id> 24 <name>shopA</name> 25 </shop> 26 </shops> 27 </city>

追記修正

質問の仕様が不明確で申し訳ありません。
nameが重複するshopは、idでも重複します。
以下のような可能性が考えられます。
city直下のshopsがユニークであることを期待します。

JavaScript

1 <var xml = `<?xml version="1.0" encoding="UTF-8"?> 2 <city> 3 <shops> 4 <shop> 5 <id>1</id> 6 <name>shopA</name> 7 </shop> 8 </shops> 9 <shops> 10 <shop> 11 <id>2</id> 12 <name>shopB</name> 13 </shop> 14 </shops> 15 <shops> 16 <shop> 17 <id>1</id> 18 <name>shopA</name> 19 </shop> 20 </shops> 21 <shops> 22 <shop> 23 <id>1</id> 24 <name>shopA</name> 25 </shop> 26 </shops> 27 </city>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2021/07/17 00:58

このコードは、どういう環境で動作するのですか? トランスパイルをしているならば、その環境を書いた方がいいかもしれません。質問タグに追記もお願いします。
tkshp

2021/07/17 03:51

デバッグ方法を追記しました。 特に変換はしていなく、htmlファイルで<script>タグでJavaScriptを書いて、Chromeのログで確認しているだけです。
Lhankor_Mhy

2021/07/17 04:14

そのやり方では文法エラーが出ると思いますが…… 少なくとも、当方の環境では動きません。
think49

2021/07/17 05:40

> XMLによっては、以下のように同名のshopsが3回以上出現する場合もありうることに気づき、 <name>の内容(子のテキストノード値)が「XML内でユニーク」を期待しているように読めますが、質問コードでは「city要素配下においてユニーク」を期待しているように読めます。 どちらを期待していますか。
think49

2021/07/17 05:42

idの重複チェックが入ってないのも気になります。 サンプルのXMLを読む限りでは、idは「XML文書内でユニーク」を期待しているように読めますが…。
tkshp

2021/07/18 11:06

不明確な仕様の質問で申し訳ありませんでした。 質問に追記して仕様を明確にいたしました。
guest

回答1

0

ベストアンサー

文法エラーはご愛敬として、Setにnameのテキストを詰めていって、都度重複するかチェックするやり方はどうでしょう。

こんな感じでどうでしょうか。

js

1 var xml = `<?xml version="1.0" encoding="UTF-8"?> 2 <city> 3 <shops> 4 <shop> 5 <id>1</id> 6 <name>shopA</name> 7 </shop> 8 </shops> 9 <shops> 10 <shop> 11 <id>2</id> 12 <name>shopB</name> 13 </shop> 14 </shops> 15 <shops> 16 <shop> 17 <id>3</id> 18 <name>shopA</name> 19 </shop> 20 </shops> 21 </city>`; 22 23 var xmlDoc = $.parseXML(xml); 24 var city = $(xmlDoc).children("city"); 25 const set = new Set(); 26 city.find('name').each(function (i, e) { 27 if (set.has(e.textContent)) $(e).parents('shops').remove(); 28 set.add(e.textContent); 29 }); 30 31 32 console.log(city.html()); 33/* 34 35 <shops> 36 <shop> 37 <id>1</id> 38 <name>shopA</name> 39 </shop> 40 </shops> 41 <shops> 42 <shop> 43 <id>2</id> 44 <name>shopB</name> 45 </shop> 46 </shops> 47 48*/

投稿2021/07/17 04:48

Lhankor_Mhy

総合スコア36960

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

tkshp

2021/07/19 06:03

ご回答ありがとうございます。 文法を理解するのに時間がかかってしまい、コメントが遅くなり申し訳ありません。 また、Setオブジェクトというものを初めて知って、IE11でも使えるのか気になったのですが、 検証したところ、IE11でも正常に使えそうだということがわかりました。 ご教示いただきありがとうございました。
Lhankor_Mhy

2021/07/19 06:36

お役に立てたようで何よりです。 私も含めここの回答者は、普通にIE11をスルーすると思いますので、IE条件があるならば明示をすることをおすすめします。
tkshp

2021/07/21 06:15

コメントありがとうございます。 IE11の件のご教示もありがとうございます。承知しました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問