JavaScriptまたはjQueryでHTMLを正規化する方法は?


84

タグは複数の属性を持つことができます。コードに属性が表示される順序は重要ではありません。例えば:

<a href="#" title="#">
<a title="#" href="#">

JavascriptでHTMLを「正規化」して、属性の順序が常に同じになるようにするにはどうすればよいですか?常に同じである限り、どちらの順序を選択してもかまいません。

更新:私の当初の目標は、わずかな違いで2つのHTMLページを(JavaScriptで)簡単に差分できるようにすることでした。ユーザーは別のソフトウェアを使用してコードを編集できるため、属性の順序が変わる可能性があります。これにより、差分が冗長になりすぎます。

答え:まあ、最初にすべての答えに感謝します。そして、はい、それは可能です。これが私がそれをどうやってやったかです。これは概念実証であり、確実に最適化できます。

function sort_attributes(a, b) {
  if( a.name == b.name) {
    return 0;
  }

  return (a.name < b.name) ? -1 : 1;
}

$("#original").find('*').each(function() {
  if (this.attributes.length > 1) {
    var attributes = this.attributes;
    var list = [];

    for(var i =0; i < attributes.length; i++) {
      list.push(attributes[i]);
    }

    list.sort(sort_attributes);

    for(var i = 0; i < list.length; i++) {
      this.removeAttribute(list[i].name, list[i].value);
    }

    for(var i = 0; i < list.length; i++) {
      this.setAttribute(list[i].name, list[i].value);
    }
  }
});

差分の2番目の要素についても同じです$('#different')。今$('#original').html()$('#different').html()同じ順序で属性を持つHTMLコードを示しています。


59
これの必要性は何ですか?
rahul 2010

40
@rahul:実際、これにはかなり興味深いニーズがあります。ページのgzip圧縮を大幅に改善できます。
ヘイレム2010

11
ああ、Javascriptでは...圧縮についてはこれだけです。その時の必要性はわかりません。
ヘイレム2010

13
@Julien:JavaScriptコードが実行されるまでに、ページはすでにクライアントに送信されています。そのとき、それが圧縮にどのように役立つかわかりません。
casablanca 2010

22
OPが要求することを実行しようとするための実際の有効な使用法があります。WYSIWYGエディターを使用してWikiを駆動します。私が取り組んでいるプロジェクトはまさにそれを行っており、ウィキを編集するたびにエディターが属性の順序を逆にして、不要な差分を作成していました。差分を避けるために、保存する前に、送信されたHTMLの属性をバックエンドでアルファベット順に並べ替えることになります。送信する前に、JavaScriptでその並べ替えを簡単に行うことができます。
フランクファーマー

回答:


68

JavaScriptは、実際にはテキストベースのHTML形式のWebページを表示するのではなく、DOMまたはドキュメントオブジェクトモデルと呼ばれるツリー構造として表示します。DOM内のHTML要素属性の順序は定義されていないため(実際、Svendのコメントとして、それらはDOMの一部でもありません)、JavaScriptが実行される時点でそれらを並べ替えるという考えは関係ありません。

私はあなたが達成しようとしていることを推測することしかできません。JavaScript /ページのパフォーマンスを向上させるためにこれを行おうとしている場合、ほとんどのHTMLドキュメントレンダラーはすでに属性アクセスの最適化に多大な労力を費やしていると思われるため、そこで得られるものはほとんどありません。

ページがネットワーク経由で送信されるときにページのgzip圧縮をより効果的にするために属性を注文しようとしている場合は、JavaScriptがその時点以降に実行されることを理解してください。代わりに、サーバー側で実行されるものを確認することをお勧めしますが、それはおそらく価値よりも厄介です。


8
JavaScriptはサーバー側で実行できます。
Matt Kantor

属性はドキュメントツリーの一部とは見なされません(自然に順序付けを使用します)。したがって、Attrはノードインターフェイスを継承しますが、DOM Core 2は、属性w3.org/TR/DOM-Level-2-Core/core.html#ID-637646024
Svend

35

HTMLを取得し、DOM構造に解析します。次に、DOM構造を取得し、HTMLに書き戻します。書き込み中に、安定ソートを使用して属性をソートします。これで、HTMLは属性に関して正規化されます。

これは、物事を正規化する一般的な方法です。(正規化されていないデータを解析してから、正規化された形式で書き戻します)。

HTMLを正規化する理由はわかりませんが、それはあります。データはデータです。;-)


1
コード例はありますか?私は似たようなことをしようとしましたが、うまくいきませんでした。
ジュリアン

12

これは概念実証であり、確実に最適化できます。

function sort_attributes(a, b) {
  if( a.name == b.name) {
    return 0;
  }

  return (a.name < b.name) ? -1 : 1;
 }

$("#original").find('*').each(function() {
  if (this.attributes.length > 1) {
    var attributes = this.attributes;
    var list = [];

    for(var i =0; i < attributes.length; i++) {
      list.push(attributes[i]);
    }

     list.sort(sort_attributes);

    for(var i = 0; i < list.length; i++) {
      this.removeAttribute(list[i].name, list[i].value);
    }

     for(var i = 0; i < list.length; i++) {
       this.setAttribute(list[i].name, list[i].value);
    }
  }
 });

差分の2番目の要素$( '#different')についても同じです。$( '#original')。html()と$( '#different')。html()は、同じ順序で属性を持つHTMLコードを表示します。


HTMLコンテンツをXMLで生成し、xsltを使用してレンダリングするとよいと思います。あなたは確かにより良い出力を得るでしょう。
ナサララ2011年

8

あなたはfirebugでHTMLタブを開くことを試みることができます、属性は常に同じ順序です


4
これだけではあまり役に立ちません。これは、DOMからHTMLを再作成しているためですが、これには特定の属性の反復順序があります(または、Firebugがそれらを手動でソートします)。Julienはこれを利用して、同じ方法を使用してHTMLを書き出すことができます。
Matt Kantor

5

実際、私はいくつかの正当な理由を考えることができます。1つは、IDマッチングと、意味的に同等の行を「異なる」とマークできることが非常に煩わしい「diff」タイプのツールで使用するための比較です。

本当の質問は「なぜJavascriptで」ですか?

この質問は、「問題があり、答えがあると思います...しかし、答えにも問題があります」という「におい」です。

OPがなぜこれをしたいのを説明するなら、良い答えを得る可能性は劇的に上がるでしょう。


2

「これの必要性は何ですか?」という質問。回答:コードが読みやすく、理解しやすくなります。

ほとんどのUIがダメな理由...多くのプログラマーは、ユーザーの仕事を簡素化する必要性を理解していません。この場合、ユーザーの仕事はコードを読んで理解することです。属性を注文する理由の1つは、コードをデバッグおよび保守する必要がある人間のためです。プログラムがよく知っている順序付きリストは、彼の仕事を容易にします。彼は、属性をより迅速に見つけたり、欠落している属性を認識したり、属性値をより迅速に変更したりできます。


あなたがその質問について十分長い間考えていなかったと思います。質問に対する実用的な解決策でさえ、あなたがここで言うことには対処しません。
issa marie tseng 2010

OPがJavascriptでこれを実行したいと思うのはなぜだと思いますか?それはです可能、サーバー側(ビルド時?)Javascriptのソリューションを念頭に置いてあったことが、それはStackOverflowのポストにそれを言及しなかっただろう、誰かがそれを行うのに十分な経験とは考えにくいです。OPがブラウザ内のHTMLエディタを実装している可能性もありますが、それも疑わしいようです。
とがった2010

0

これは誰かがソースを読んでいるときにのみ問題になるので、私にとっては最初にセマンティック属性であり、次にセマンティック属性ではありません...

もちろん例外もあります。たとえば、連続する<li>があり、すべてが1つの属性で、他の属性が一部のみである場合は、共有属性がすべて最初にあり、その後に個別の属性が続くことを確認できます。 。

<li a = "x"> A </ li>
<li a = "y" b = "t"> B </ li>
<li a = "z"> C </ li>

(「b」属性が「a」よりも意味的に有用である場合でも)

あなたはその考えを理解します。


0

htmlのコンテンツがxmlとして渡され、xsltを介してレンダリングされる場合、実際には可能だと思います...したがって、XMLの元のコンテンツは任意の順序にすることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.