ホームページ バックエンド開発 XML/RSS チュートリアル XML ボリュームの実践ヒント (5): 構造ツリー図

XML ボリュームの実践ヒント (5): 構造ツリー図

Feb 10, 2017 pm 04:22 PM
xml

動機:
初めてバイナリーツリーを作ろうと思ったのは、会社の構造図を作る必要があったからです。 以前のアプローチは、グラフィック ソフトウェアを使用して直接絵を描くことでした。見た目は素晴らしいですが、変更があるたびに新しいものをペイントする必要があります。 一方、Web ページ上の行の表示とレイアウトはかなり制限されています。動的に生成されたデータに基づいて植字や配置を行うのは非常に難しく、美観も満足のいくものではありません。 いろいろ試した結果、データ操作にはXML+XSLを使用し、行の美化にはVMLを使用し、オブジェクトの配置にはJAVASCRIPTを使用することにしました。

資料:
XML ボリューム構造ツリー図
2 つのファイルがあります: flow2.xml と flow2.xsl
効果:
ここを参照
説明:
バイナリ ツリーのアイデア (1)

<html xmlns:v="urn:schemas-microsoft-com:vml">
<STYLE>
v\:* { BEHAVIOR: url(#default#VML) } 
</STYLE>
<v:group id="group1" name="group1" coordsize = "100,100">
…
</v:group>
ログイン後にコピー

これらは VML の基本形式です。詳しくは説明しません。

XML はツリー構造です。各データを読み取るには、この
XML データ ツリーをたどる必要があります。再帰操作は XSL の利点の 1 つです。
また、トラバーサル操作を実行するために他のさまざまな方法を使用して失敗した後、XSL を使用することにしました。

<FlowRoot>
<vcTitle>二叉树--结构图</vcTitle>
<Author>Sailflying</Author>
<Email>sailflying@163.net</Email>
<FlowNode>
<iProcess>1</iProcess>
<vcCourse>第一个节点</vcCourse>
<iNextYes>
<FlowNode>
<iProcess>2</iProcess> 
<vcCourse>第二个节点</vcCourse>
<iNextYes>…</iNextYes> 
<iNextNo>…</iNextNo> 
</FlowNode>
</iNextYes> 
<iNextNo>
<FlowNode>
<iProcess>3</iProcess> 
<vcCourse>第三个节点</vcCourse>
<iNextYes>…</iNextYes> 
<iNextNo>…</iNextNo> 
</FlowNode>
</iNextNo> 
</FlowNode>
</FlowRoot>
ログイン後にコピー

ロジックは非常に単純です。現在のノード (1) の下に 2 つの子ノード (2、3) があります。
ノード 2 とノード 3 をノード 1 の左下と右下に配置するだけです。
ここでは、表示しやすいように、左側と右側のノードの接続線にそれぞれ緑と赤を使用しています。

XSL の再帰関数については前に説明しましたが、各詳細な
表示ステップをより明確に確認するには、次のコードを模倣してアラート ステートメントを追加するだけです。

<xsl:template match="FlowNode">…<SCRIPT language="JavaScript1.2">…alert(&#39;逐步显示&#39;);…</SCRIPT>…</xsl:template>
ログイン後にコピー

上のスローモーションを見て、私の考えが理解できますか?



二分木のアイデア (2)
私のアイデアは非常に単純です:
(1) 現在のノードのデータを読み取り、VML を使用して新しいオブジェクトを生成します。
オブジェクトに初期値を割り当てます(名前、ID、スタイルなど)
(2) スクリプトコントロールを使用して現在のオブジェクトを配置します
(3) 現在のノードとその親ノードの間に矢印と線を追加します。
(4) 現在のノードの子ノードを探し続け、最後までループします。
つまり、すべてのノードが走査され、ツリーが生成されました。

<xsl:template match="FlowNode">…<xsl:apply-templates />…</xsl:template> 
<xsl:template match="iNextYes"><xsl:apply-templates select="./FlowNode" /></xsl:template>
<xsl:template match="iNextNo"><xsl:apply-templates select="./FlowNode" /></xsl:template>
ログイン後にコピー

上記の 3 つのモジュール (テンプレート) によって、再帰的なプロセス全体が完了します。

最初のテンプレート
は、現在のノードの各サブノードのテンプレートと一致するときに次の 2 つのテンプレートを呼び出します。後の 2 つのテンプレートは、特定の実行中に最初のテンプレート
を呼び出します。これは再帰関数と同等です。

構文:

現在のノードの各子ノードのテンプレートと順番に一致させるには、この要素の基本形式 を使用する必要があります。

それ以外の場合、一致するノードは、 などの選択パラメーターの XPath 式の値によって決定されます


(1) と(2) どちらも、select パラメータで指定された式の文字列値を返します。

検索条件が同じなので、戻り値も同じになります。

ただ、使われる場面によって書き方が違うだけです。



(1)

(2) {./iProcess/text()}



いくつかの変数とノードがここで定義されていますこれらの変数を基に計算式を呼び出して位置決めを行います。

root_left //ルートの左マージン = すべてのリーフの割り当てられた幅 (y*10) + すべてのリーフの幅 (y*50) + 左マージンの基本値 (10)
root_top //ルートの上マージン = 基本の上マージン Value (10)

objOval //現在のオブジェクトはオブジェクトです

objOval_iProcess //現在のオブジェクトのステップ値
objParentOval //現在のオブジェクトの親ノードはオブジェクトです
objParentOval_iProcess //現在のオブジェクトの親ノードのステップ値
objParent_name //現在のオブジェクトの親ノードの名前
Leaf_left //現在のオブジェクトのすべての子ノードの左の葉の数
Leaf_right //右の葉の数現在のオブジェクトのすべての子ノード内
Leaf_sum //現在のオブジェクトのすべての子ノード内のリーフの数

Leaf: 現在のノードには子ノードがないことを意味します

ノードの位置決め式:

(1) 現在のノードはルートノードです

//根的位置
SobjOval.style.left=parseInt(root_left);
SobjOval.style.top=parseInt(root_top);
//parseInt() 函数的作用是取整数值,如果不是则为NAN
//isNaN()函数的作用是判断parseInt取得的是否为整数
ログイン後にコピー

(2) 現在のノードは親ノードの左の子ノードです


1) 判定条件は以下のとおりです: 現在のオブジェクトの親の名前ノード = 'iNextYes'

2) 右側の子リーフがある場合、式は次のようになります:

現在のノードの左側 = 親ノードの左側 - 現在のノードの右側の子リーフ の合計幅 -現在のノードの幅

3) 右の子リーフがなく、左の子リーフがある場合、式は次のようになります:
現在のノードの左 = 親ノードの左 - ノードの合計幅現在のノードの左の子リーフ

4) 現在のノード自体がリーフの場合、式は次のようになります:
現在のノードの左 = 親ノードの左 - 現在のノードの幅

...



(3) 現在のノードが親ノードの右側の子ノードである

1) 判定の条件は、現在のオブジェクトの親ノードの名前 = 'iNextNo'

2) がある場合左側の子リーフ、式は次のとおりです:

現在のノードの左側 = 親ノードの左側 + 現在のノードの左側の子リーフ 合計の幅 + 現在のノードの幅

3)如果不存在左边子叶子,但存在右边子叶子,则公式为:
当前节点的left=父节点的left + 当前节点的右边子叶子的总宽度

4)如果当前节点本身就是叶子,则公式为:
当前节点的left=父节点的left + 当前节点的宽度

(2)和(3)的公式都是得到当前节点的left,我们还需要得到当前节点的top
很简单的公式:当前节点的top=父节点的top + 偏移量(80)

二叉树思路(3)
连接线条的定位思路:
(1)找到当前节点和父节点的位置
(2)判断当前节点是父节点的左边子节点,还是右边子节点
(3)画线条

这里定义了一些变量。


objOval //当前节点,是一个object
objParentOval //当前对象的父节点,是一个object
objLine //当前线条,是一个object


线条的定位公式:


from="x1,y1" to="x2,y2" 是 VML 里定位线条的方式

当前节点是父节点的左边子节点,则公式为:
from = 父节点的left + 偏移量(15) , 父节点的top + 偏移量(32)
to = 父节点的left + 偏移量(30) , 父节点的top - 偏移量(2)

当前节点是父节点的右边子节点,则公式为:
from = 父节点的left + 偏移量(35) ,父节点的top + 偏移量(32)
to = 父节点的left + 偏移量(20) ,父节点的top - 偏移量(2)


我所能想到的也就这么多了。

如果只是单纯的做一个公司结构图的话,会更简单很多。
下面是赛扬的思路,我也是在他的基础上深入一点而已。

首先计算最下层节点个数,得出宽度,
然后应该根据节点的从属关系计算其上层节点位置,递归。
每一层级的节点要按从属关系先排序
首先设“基本值”=节点应向右偏移量
每个包含子节点的节点的left值等于它所拥有的节点所占宽度的一半加上基本值

后话:

最近不知为何,网络一直都不好。断线的时间比在线的时间多。
所以没对代码简化,其实,要完善的功能还有很多,比如:
需要加右键菜单
右键菜单内含新建节点、修改节点名称、改变关联关系等
在每一个节点上都可右键打开这个节点的右键菜单

讲解:
1)flow2.xml 是数据文件,相信大家都不会有问题。
2)flow2.xsl 是格式文件,有几个地方要注意。
(1)脚本中:

(1) <xsl:value-of select="./iProcess/text()" /> ;(2) {./iProcess/text()}
ログイン後にコピー

(1)和(2)的作用都是返回由 select 参数给出的表达式的字符串值。
他们的搜索条件相同,所以返回的值也一样。
只不过是使用的场合不同,他们的书写形式也就不一样。

<xsl:apply-templates select="team" order-by="blue_ID"/>
ログイン後にコピー


比如我们想生成以下代码

内容



我们假设名称为“name”,参数值为XML数据中当前节点下面的子节点book的值


第一种写法是先加属性名称,再加参数值

<p>
<xsl:attribute name="name">
<xsl:value-of select="./book/text()"/> </xsl:attribute>
内容 
</p>
ログイン後にコピー

第二种写法是直接加属性名称和参数值

<p name="{./book/text()}">内容</p>
ログイン後にコピー

具体的使用你可以看我写的代码中的例子。

XSL在正式的 xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 的标准里

<xsl:value-of select="./book/text()"/>
ログイン後にコピー


作用是:只是把他的文本值写出来,而

<xsl:value-of select="./book"/>
ログイン後にコピー


是把他的文本值和他的所有子节点的内容显示出来。
大家可以试验一下,输出一个有子节点的,一个无子节点的
看看显示的结果是否相同。


(2)需要注意:

IE5 不支持
要用

<tag><xsl:attribute name="att"><xsl:value-of select="xpath"></xsl:attribute>
ログイン後にコピー

命名空间要用

xmlns:xsl="http://www.w3.org/TR/WD-xsl"
<?xml version="1.0" encoding="gb2312" ?>
ログイン後にコピー

另外说一点:
在大多的XML教科书中所显示的代码中很少会加上encoding="gb2312" ,
因此我们在XML中用到中文的时候会报错,原因就是没有写这个申明。

后记:
这里说的是一种思路。如果触类旁通,自然能够派上用场。 

以上就是XML卷之实战锦囊(5):结构树图的内容,更多相关内容请关注PHP中文网(www.php.cn)!

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

PowerPoint を使用して XML ファイルを開くことはできますか? PowerPoint を使用して XML ファイルを開くことはできますか? Feb 19, 2024 pm 09:06 PM

XML ファイルは PPT で開くことができますか? XML、Extensible Markup Language (Extensible Markup Language) は、データ交換とデータ ストレージで広く使用されている汎用マークアップ言語です。 HTML と比較して、XML はより柔軟であり、独自のタグとデータ構造を定義できるため、データの保存と交換がより便利で統一されます。 PPT (PowerPoint) は、プレゼンテーションを作成するために Microsoft によって開発されたソフトウェアです。包括的な方法を提供します。

Python を使用した XML データのマージと重複排除 Python を使用した XML データのマージと重複排除 Aug 07, 2023 am 11:33 AM

Python を使用した XML データのマージと重複排除 XML (eXtensibleMarkupLanguage) は、データの保存と送信に使用されるマークアップ言語です。 XML データを処理するとき、複数の XML ファイルを 1 つにマージしたり、重複データを削除したりする必要がある場合があります。この記事では、Python を使用して XML データのマージと重複排除を実装する方法と、対応するコード例を紹介します。 1. XML データのマージ 複数の XML ファイルがある場合、それらをマージする必要があります。

Python で XML データを CSV 形式に変換する Python で XML データを CSV 形式に変換する Aug 11, 2023 pm 07:41 PM

Python の XML データを CSV 形式に変換する XML (ExtensibleMarkupLanguage) は、データの保存と送信に一般的に使用される拡張可能なマークアップ言語です。 CSV (CommaSeparatedValues) は、データのインポートとエクスポートに一般的に使用されるカンマ区切りのテキスト ファイル形式です。データを処理するとき、分析や処理を容易にするために、XML データを CSV 形式に変換する必要がある場合があります。 Pythonは強力です

Python を使用した XML データのフィルタリングと並べ替え Python を使用した XML データのフィルタリングと並べ替え Aug 07, 2023 pm 04:17 PM

Python を使用した XML データのフィルタリングと並べ替えの実装 はじめに: XML は、データをタグと属性の形式で保存する、一般的に使用されるデータ交換形式です。 XML データを処理するとき、多くの場合、データのフィルタリングと並べ替えが必要になります。 Python には、XML データを処理するための便利なツールとライブラリが多数用意されています。この記事では、Python を使用して XML データをフィルタリングおよび並べ替える方法を紹介します。 XML ファイルの読み取り 始める前に、XML ファイルを読み取る必要があります。 Python には XML 処理ライブラリが多数ありますが、

PHP を使用して XML データをデータベースにインポートする PHP を使用して XML データをデータベースにインポートする Aug 07, 2023 am 09:58 AM

PHP を使用した XML データのデータベースへのインポート はじめに: 開発中、さらなる処理や分析のために外部データをデータベースにインポートする必要がよくあります。一般的に使用されるデータ交換形式として、XML は構造化データの保存と送信によく使用されます。この記事では、PHP を使用して XML データをデータベースにインポートする方法を紹介します。ステップ 1: XML ファイルを解析する まず、XML ファイルを解析し、必要なデータを抽出する必要があります。 PHP には XML を解析するためのいくつかの方法が用意されており、最も一般的に使用されるのは Simple を使用する方法です。

Python は XML と JSON 間の変換を実装します Python は XML と JSON 間の変換を実装します Aug 07, 2023 pm 07:10 PM

Python は XML と JSON 間の変換を実装します はじめに: 日常の開発プロセスでは、異なる形式間でデータを変換する必要があることがよくあります。 XML と JSON は一般的なデータ交換形式であり、Python ではさまざまなライブラリを使用して XML と JSON の間で変換できます。この記事では、一般的に使用されるいくつかの方法をコード例とともに紹介します。 1. Python で XML を JSON に変換するには、xml.etree.ElementTree モジュールを使用できます。

Python を使用した XML でのエラーと例外の処理 Python を使用した XML でのエラーと例外の処理 Aug 08, 2023 pm 12:25 PM

Python を使用した XML でのエラーと例外の処理 XML は、構造化データの保存と表現に使用される一般的に使用されるデータ形式です。 Python を使用して XML を処理すると、エラーや例外が発生することがあります。この記事では、Python を使用して XML のエラーと例外を処理する方法を紹介し、参考用のサンプル コードをいくつか示します。 Try-Except ステートメントを使用して XML 解析エラーを捕捉する Python を使用して XML を解析すると、時々、次のようなエラーが発生することがあります。

Python は XML 内の特殊文字とエスケープ シーケンスを解析します Python は XML 内の特殊文字とエスケープ シーケンスを解析します Aug 08, 2023 pm 12:46 PM

Python は XML 内の特殊文字とエスケープ シーケンスを解析します XML (eXtensibleMarkupLanguage) は、異なるシステム間でデータを転送および保存するために一般的に使用されるデータ交換形式です。 XML ファイルを処理する場合、特殊文字やエスケープ シーケンスが含まれる状況に遭遇することが多く、これにより解析エラーやデータの誤解が生じる可能性があります。したがって、Python を使用して XML ファイルを解析する場合は、これらの特殊文字とエスケープ シーケンスの処理方法を理解する必要があります。 1. 特殊文字と

See all articles