数学、電気の勉強始めました!プログラムにも挑戦しています!|ω・)ノ

ねごとめも背景

# ねごとめも

# カウンター

# プロフィール

negotoy

Author:negotoy
電気の勉強始めました!
テキストエディタを使ってプログラミングに挑戦中。
fc2 ブログに公開しているテンプレート等は、自由にカスタマイズして、ご活用ください。
プログラム実行の前に必ずコードの確認をお願いします。

# 最新記事

# カレンダー

12 | 2017/03 | 03
- - - 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 -

# スポンサードリンク

今回は前回の javascript タグ削除テスト(2)の続き。
[ 修正箇所 ] 1) XML宣言, DTD宣言の記述を無視するように訂正。
2) textarea タグの内容を CDATA として出力。 ( textarea 内に textarea タグが存在する場合エラー )
3) html5 で定義されている空要素に、タグを閉じる記号 ( "/" ) 閉がなくても XML として出力。
その他、色々と修正。
textarea の HTML5 ドキュメントから XML ツリーを生成、文字列として出力まで。



■ xhtml.php


<?php
	class XHTML extends DOMDocument
	{
		private $doc;
		function __construct($version="1.0",$encoding="utf-8")
		{
			$this->doc=new parent($version,$encoding);
		}
		
		public function saveHTML()
		{
			return $this->doc->saveXML();
		}
		
		public function loadXHTML($contents,$option=0)
		{
			$this->setDomDocument($contents);
			/*
			$this->doc->loadHTML("<svg>a</svg>");
			$script=$this->doc->getElementsByTagName("script")->item(0)->nodeName;
			echo($script);
			$this->doc->loadXML($contents);
			*/
		}
		
		public function saveXHTML()
		{
			return $this->doc->saveXML();
		}
		
		private function setDomDocument($contents)
		{
			$doc=$this->doc;
			//$doc->preserveWhiteSpace=true;
			$doc->formatOutput=true;
			$target=$doc->createElement("root");
			//$target->setAttribute("xmlns","http://www.w3.org/1999/xhtml");
			$target=$doc->appendChild($target);
			$text="";
			$prev="";
			$type="text";
			$nodeName="";
			$attribute="";
			$quot_type="";
			$result="";
			foreach(str_split($contents) as $str)
			{
				switch($str)
				{
					case "<" :
							switch($type)
							{
								case "text" :
										$type="tagL";
										if(strlen($text)!=0)
										{
											$target->appendChild($doc->createTextNode($text));
											$text="";
										}
								break;

								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;

								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;

								case "dtd" :

								break;

								default :
										$text.=$str;
							}
					break;

					case ">" :
							switch($type)
							{
								case "tagL" :
										$nodeName=strtolower(trim($text));
										switch($nodeName)
										{
												case "area" :
												case "base" :
												case "br" :
												case "col" :
												case "command" :
												case "embed" :
												case "hr" :
												case "img" :
												case "input" :
												case "keygen" :
												case "link" :
												case "meta" :
												case "param" :
												case "source" :
												case "track" :
												case "wbr" :
														$target=$target->appendChild($doc->createElement($nodeName));
														$target=$target->parentNode;
														$text="";
														$type="text";
												break;
												
												case "textarea" :
														$target=$target->appendChild($doc->createElement($nodeName));
														$text="";
														$type="textArea";
												break;
												
												default :
														$target=$target->appendChild($doc->createElement($nodeName));
														$text="";
														$type=($nodeName=="script")? "script" : "text";
										}
								break;

								case "tagR" :
										$target=$target->parentNode;
										$text="";
										$type="text";
								break;

								case "commentR" :
										$text=preg_replace("/^--|--$/si","",$text);
										$target->appendChild($doc->createComment($text));
										$text="";
										$type="text";
								break;

								case "cdataR" :
										$text=preg_replace("/^\[[a-zA-Z]+\[|]]$/si","",$text);
										$target->appendChild($doc->createCDATASection($text));
										$text="";
										$type="text";
								break;
								
								case "script" :
									if($quot_type==""&&preg_match("/[.]*<\/script$/si",$text))
									{
										$text=preg_replace("/^.*<!\[CDATA\[(.*)\]\]>.*<\/script$/si","$1",$text);
										$text=preg_replace("/<\/script$/si","",$text);
										if(strlen(trim($text))!=0)
										{
											$target->appendChild($doc->createCDATASection($text));
										}
										$target=$target->parentNode;
										$type="text";
										$text="";
									}
									else
									{
										$text.=$str;
									}
								break;

								case "textArea" :
									if($quot_type==""&&preg_match("/.*<\/textarea$/si",$text))
									{
										$text=preg_replace("/^textarea|<\/textarea$/si","",$text);
										if(strlen(trim($text))!=0)
										{
											$target->appendChild($doc->createCDATASection($text));
										}
										$target=$target->parentNode;
										$type="text";
										$text="";
									}
									else
									{
										$text.=$str;
									}
								break;
								
								case "attribute" :
								case "valueL" :
											$text=preg_replace("/[ 	\r\n]*=[ 	\r\n]*/s","=",trim($text));
											foreach(explode(" ",$text) as $val)
											{
												if(!empty($val))
												{
													$attr=explode("=",$val);
													if(count($attr)==2)
													{
														$target->setAttribute(trim($attr[0]),trim($attr[1]));
													}
													else
													{
														$target->setAttribute(trim($attr[0]),trim($attr[0]));
													}
													$attribute=trim($val[0]);
												}
											}
											switch($nodeName)
											{
												case "area" :
												case "base" :
												case "br" :
												case "col" :
												case "command" :
												case "embed" :
												case "hr" :
												case "img" :
												case "input" :
												case "keygen" :
												case "link" :
												case "meta" :
												case "param" :
												case "source" :
												case "track" :
												case "wbr" :
														$target=$target->parentNode;
														$type="text";
														$text="";
												break;
												
												case "textarea" :
														$type="textArea";
														$text="";
												break;
												
													default:
															$type=($nodeName=="script")? "script" : "text";
															$text="";
											}
								break;

								case "dtd" :
										$type="text";
										$text="";
								break;
								
								
								default :
										$text.=$str;
							}
					break;

					case "/" :
							switch($type)
							{
								case "tagL" :
										$nodeName=strtolower(trim($text));
										switch($nodeName)
										{
												case "area" :
												case "base" :
												case "br" :
												case "col" :
												case "command" :
												case "embed" :
												case "hr" :
												case "img" :
												case "input" :
												case "keygen" :
												case "link" :
												case "meta" :
												case "param" :
												case "source" :
												case "track" :
												case "wbr" :
														$target=$target->appendChild($doc->createElement($nodeName));
														$type="tagR";
												break;
												
												default:
														$type="tagR";
										}
								break;

								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;

								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;

								case "attribute" :
										if(strlen(trim($text))!=0)
										{
											$attr=trim($text);
											foreach(explode(" ",$attr) as $val)
											{
												if(!empty($val))
												{
													$val=explode("=",$val);
													if(count($val)==1)
													{
														$target->setAttribute(trim($val[0]),trim($val[0]));
													}
													else
													{
														$target->setAttribute(trim($val[0]),trim($val[1]));
													}
												}
											}
										}
										$type="tagR";
								break;

								case "valueL" :
										//text.append(str);
								break;
								case "dtd" :

								break;

								default :
										$text.=$str;
							}
					break;

					case "!" :
							switch($type)
							{
								case "tagL" :
										if($prev=="<")
										{
											$type="dtd";
										}
								break;

								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;

								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;

								case "attribute" :
								case "dtd" :

								break;

								default :
										$text.=$str;
							}
					break;

					case "?" :
							switch($type)
							{
								case "tagL" :
										if($prev=="<")
										{
											$type="dtd";
										}
								break;

								default :
										$text.=$str;
							}
					break;

					case "-" :
							switch($type)
							{
								case "dtd" :
										if($prev=="-")
										{
											$type="commentL";
										}
										$text.=$str;
								break;

								case "commentL" :
										if($prev=="-")
										{
											$type="commentR";
										}
										$text.=$str;
								break;

								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;

								default :
										$text.=$str;
							}

					break;

					case "[" :
							switch($type)
							{
								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;

								case "dtd" :
										if($prev=="!")
										{
											$type="cdataC";
										}
										$text.=$str;
								break;

								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;

								case "attribute":

								break;

								default:
										$text.=$str;
							}
					break;

					case "]" :
							switch($type)
							{
								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;

								case "cdataC" :
										if($prev=="]")
										{
											$type="cdataR";
										}
										$text.=$str;
								break;

								case "attribute" :
								case "dtd" :

								break;

								default:
										$text.=$str;
							}
					break;

					case " " :
					case "	" :
							switch($type)
							{
								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;

								case "cdataR" :
										$type="cdataC";
										$text.=$str;

								break;

								case "tagL" :
										$nodeName=strtolower(trim($text));
										$target=$target->appendChild($doc->createElement($nodeName));
										$text="";
										$type="attribute";
								break;

								case "dtd" :

								break;
								
								default:
										$text.=$str;
							}
					break;
					
					case "=" :
							switch($type)
							{
								case "attribute" :
										$type="valueL";
										$attribute=trim($text);
										$text.=$str;
								break;

								case "valueR" :
									if($quot_type=="")
									{
											$type="valueL";
											$attribute=trim($text);
									}
									else
									{
										$text.=$str;
									}
								break;
								
								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;

								case "dtd" :

								break;
								
								default:
										$text.=$str;
							}
					break;

					case "'" :
					case "\"" :
							switch($type)
							{
								case "valueL" :
										if($quot_type=="")
										{
											$quot_type=$str;
											$type="valueR";
											$text="";
										}
								break;

								case "valueR" :
										if($quot_type==$str)
										{
											$attrs=explode(" ",trim($attribute));
											for($i=0;$i<count($attrs);$i++)
											{
												if(!empty($attrs[$i]))
												{
													$result=(count($attrs)-1!=$i)? $attrs[$i] : $text;
													$equal=explode("=",$attrs[$i]);
													if(count($attrs)!=0&&count($equal)==1)
													{
														$target->setAttribute($attrs[$i],$result);
													}
													else
													{
														$target->setAttribute($equal[0],$equal[1]);
													}
												}
											}
											$type="attribute";
											$quot_type="";
											$text="";
										}
										else
										{
											$text.=$str;
										}
								break;

								case "script" :
										if($quot_type=="")
										{
											$quot_type=$str;
											$type="js_value";
										}
										$text.=$str;
								break;

								case "js_value" :
										if($prev!="\\")
										{
											$quot_type="";
											$type="script";
										}
										$text.=$str;
								break;
								
								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;

								case "dtd" :

								break;
								
								default:
										$text.=$str;
							}
					break;

					case "\r" :

					break;
					
					default :
							switch($type)
							{
								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;

								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;

								case "dtd" :

								break;

								default:
										$text.=$str;
							}
				}
				$prev=$str;
			}//end of foreach
			if(strlen($text)!=0)
			{
				$target->appendChild($doc->createTextNode($text));
			}
		}
	}

	if(isset($_POST["template"]))
	{
		libxml_use_internal_errors(true);
		$doc=new XHTML("1.0","utf-8");
		$contents=rawurldecode($_POST["template"]);
		$doc->loadXHTML($contents);
		//header("Content-type: text/xml");
		echo($doc->saveXHTML());
	}
?>

java 版 → java HTMLドキュメント文字列のツリー化(1)[ XML出力 ]

今回は前回の javascript タグ削除テスト(1)の続き。
前回作成した DOMDocument クラスを継承した自作 HTML クラスは、コメント, CDATA を記述した場合に、
エラーが出力されていた。
なので、今回は、コメント, CDATA が HTML ドキュメントに存在する場合は、
それぞれをコメント, CDATA として出力されるように訂正。
javascript タグの内容は前回と同じく CDATA として出力。
属性の "=" の前後に空白が含まれる場合に正しくツリー化して出力されるように訂正。
その他、色々と修正。

javascript タグを削除する流れは、
1) HTML ドキュメントを XHTML クラスの loadXHTMLの第一引数へ渡す。
2) XML としてツリー化された値が戻ってくる。
3) *サーバー上でXML ツリーから getElementsByTagName 関数、 removeChild 関数を利用して javascript タグを削除。
4) javascript タグを削除した XML ツリーを saveXHTML 関数を使用して HTML ドキュメントを文字列として出力。
*ajax を利用してクライアント側で responseXML でデータを受け取り、 javascript タグ削除も出来る?
今回も、 XML ツリーから javascript タグを削除するテストはやってない。
textarea の文字列の HTML ドキュメントを一文字づつ読み込み、
XML ツリーを生成後、文字列として出力まで。

  • *コメントの記述 [ 開始タグ( <! ) 終了タグ( --> ) ]
  • *CDATA の記述 [ 開始タグ( <![ ) 終了タグ( ]]> ) ]


■ xhtml.php


<?php
	class XHTML extends DOMDocument
	{
		private $doc;
		function __construct($version="1.0",$encoding="utf-8")
		{
			$this->doc=new parent($version,$encoding);
		}
		
		public function loadXHTML($contents,$option=0)
		{
			$this->setDomDocument($contents);
			/*
			$this->doc->loadHTML("<svg>a</svg>");
			$script=$this->doc->getElementsByTagName("script")->item(0)->nodeName;
			echo($script);
			$this->doc->loadXML($contents);
			*/
		}
		
		public function saveXHTML()
		{
			return $this->doc->saveXML();
		}
		
		private function setDomDocument($contents)
		{
			$doc=$this->doc;
			//$doc->preserveWhiteSpace=true;
			$doc->formatOutput=true;
			$root=$doc->createElement("div");
			$root->setAttribute("xmlns","http://www.w3.org/1999/xhtml");
			$target=$doc->appendChild($root);
			//$target->appendChild($doc->createComment("hoge"));
			$text="";
			$prev="\\";
			$type="text";
			$nodeName="";
			$attribute="";
			$quot_type="";
			foreach(str_split($contents) as $str)
			{
				switch($str)
				{
					case "<" :
							switch($type)
							{
								case "text" :
										$type="tagL";
										if(strlen($text)!=0)
										{
											$target->appendChild($doc->createTextNode($text));
											$text="";
										}
								break;
								
								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;
								
								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;
								
								default :
										$text.=$str;
							}
					break;
					
					case ">" :
							switch($type)
							{
								case "tagL" :
										$nodeName=strtolower(trim($text));
										$target=$target->appendChild($doc->createElement($nodeName));
										$text="";
										$type=($nodeName=="script")? "script" : "text";
								break;
								
								case "tagR" :
										$target=$target->parentNode;
										$text="";
										$type="text";
								break;
								
								case "commentR" :
										$text=preg_replace("/^--|--$/si","",$text);
										$target->appendChild($doc->createComment($text));
										$text="";
										$type="text";
								break;
								
								case "cdataR" :
										$text=preg_replace("/^\[[a-zA-Z]+\[|]]$/si","",$text);
										$target->appendChild($doc->createCDATASection($text));
										$text="";
										$type="text";
										
								break;
								
								case "attribute" :
										if(strlen(trim($text))!=0)
										{
											$attr=trim($text);
											foreach(explode(" ",$attr) as $val)
											{
												$target->setAttribute($val,$val);
											}
										}
										$text="";
										$type=($nodeName=="script")? "script" : "text";
								break;
								
								case "script" :
										if($quot_type==""&&preg_match("/[.]*<\/script$/si",$text))
										{
											$text=preg_replace("/<\/script$/si","",$text);
											$target->appendChild($doc->createCDATASection($text));
											$target=$target->parentNode;
											$type="text";
											$text="";
										}
										else
										{
											$text.=$str;
										}
								break;
								
								default :
										$text.=$str;
							}
					break;
					
					case "/" :
							switch($type)
							{
								case "tagL" :
										$type="tagR";
								break;
								
								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;
								
								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;
								
								case "attribute" :
										if(strlen(trim($text))!=0)
										{
											$attr=trim($text);
											foreach(explode(" ",$attr) as $val)
											{
												$target->setAttribute($val,$val);
											}
										}
										$type="tagR";
								break;
								
								default :
										$text.=$str;
							}
					break;
					
					case "!" :
							switch($type)
							{
								case "tagL" :
										$type="commentL";
								break;
								
								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;
								
								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;
								
								case "attribute" :
								
								break;
								
								default :
										$text.=$str;
							}
					
					break;
					
					case "-" :
							switch($type)
							{
								case "commentL" :
										if($prev=="-")
										{
											$type="commentR";
										}
										$text.=$str;
								break;
								
								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;
								
								default :
										$text.=$str;
							}
					
					break;
					
					case "[" :
							switch($type)
							{
								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;
								
								case "commentL" :
										if($prev=="!")
										{
											$type="cdataC";
										}
										$text.=$str;
								break;
								
								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;
								
								case "attribute":
								
								break;
								
								default:
										$text.=$str;
							}
					break;
					
					case "]" :
							switch($type)
							{
								case "commentR" :
										$type="commentL";
										$text.=$str;
								break;
								
								case "cdataC" :
										if($prev=="]")
										{
											$type="cdataR";
										}
										$text.=$str;
								break;
								
								case "attribute" :
								
								break;
								
								default:
										$text.=$str;
							}
					break;
					
					case " " :
							switch($type)
							{
								case "commentL" :
										$type="commentL";
										$text.=$str;
								break;
								
								case "cdataR" :
										$type="cdataC";
										$text.=$str;
										
								break;
								
								case "tagL" :
										$nodeName=strtolower(trim($text));
										$target=$target->appendChild($doc->createElement($nodeName));
										$text="";
										$type="attribute";
								break;
								
								default:
										$text.=$str;
							}
					break;
					
					case "	" :
							switch($type)
							{
								case "commentL" :
										$type="commentL";
										$text.=$str;
								break;
								
								case "cdataR" :
										$type="cdataC";
										$text.=$str;
								break;
								
								case "tagL" :
										$nodeName=strtolower(trim($text));
										$target=$target->appendChild($doc->createElement($nodeName));
										$text="";
										$type="attribute";
								break;

								default:
										$text.=$str;
							}
					break;
					
					case "=" :
							switch($type)
							{
								case "attribute" :
										$type="valueL";
										$attribute=trim($text);
								break;
								
								case "valueR" :
										$type="valueL";
										$attribute=trim($text);
								break;
								
								default:
										$text.=$str;
							}
					break;
					
					case "'" :
							switch($type)
							{
								case "valueL" :
										if($quot_type=="")
										{
											$quot_type=$str;
											$type="valueR";
											$text="";
										}
								break;
								
								case "valueR" :
										if($quot_type==$str)
										{
											$attrs=explode(" ",trim($attribute));
											for($i=0;$i<count($attrs);$i++)
											{
												$txt=((count($attrs)-1)!=$i)? $attrs[$i] : $text;
												$target->setAttribute($attrs[$i],$txt);
											}
											$type="attribute";
											$quot_type="";
											$text="";
										}
										else
										{
											$text.=$str;
										}
								break;
								
								case "script" :
										if($quot_type=="")
										{
											$quot_type=$str;
											$type="js_value";
										}
										$text.=$str;
								break;
								
								case "js_value" :
										if($prev!="\\")
										{
											$quot_type="";
											$type="script";
										}
										$text.=$str;
								break;
								
								default:
										$text.=$str;
							}
					break;
					
					case "\"" :
							switch($type)
							{
								case "valueL" :
										if($quot_type=="")
										{
											$quot_type=$str;
											$type="valueR";
											$text="";
										}
								break;
								
								case "valueR" :
										if($quot_type==$str)
										{
											$target->setAttribute($attribute,$text);
											$type="attribute";
											$quot_type="";
											$text="";
										}
										else
										{
											$text.=$str;
										}
								break;
								
								case "script" :
										if($quot_type=="")
										{
											$quot_type=$str;
											$type="js_value";
										}
										$text.=$str;
								break;
								
								case "js_value" :
										if($prev!="\\")
										{
											$quot_type="";
											$type="script";
										}
										$text.=$str;
								break;
								
								default:
										$text.=$str;
							}
					break;
					
					default :
							switch($type)
							{
								case "commentR" :
										$type="commentL";
								break;
								
								case "cdataR" :
										$type="cdataC";
								break;
							}
							
							$text.=$str;
				}
				$prev=$str;
			}
			if(strlen($text)!=0)
			{
				$target->appendChild($doc->createTextNode($text));
			}
		}
	}
	
	if(isset($_POST["template"]))
	{
		$doc=new XHTML("1.0","utf-8");
		$doc->loadXHTML(rawurldecode($_POST["template"]));
		header("Content-type: text/xml");
		echo($doc->saveXHTML());
	}

?>


訂正版 → PHP javascript タグ削除テスト(2)[ CDATA ]

今回は PHP を利用して HTML ドキュメントから javascript タグを削除するテスト。
まず最初に試したのは正規表現を利用した javascript タグの削除。
正規表現の書き方がまずいのかうまくいかない。
単純に <script>alert(0);</script> のような場合にはうまく削除出来るけど、
*<script>var js='<script>alert(0);</script>';</script> のような場合、
javascript タグ全体の削除ができないという結果。
正規表現の書き方が理解できてないからだと思ふ。

次に試したのが PHP の DOMDocument クラスの loadHTML 関数
流れとしては、
1) HTML ドキュメントを loadHTML 関数の第一引数へ渡す。
2) ツリー化された HTML から javascript タグを削除。
これで javascript タグを削除できると思いきや、使用しているタグに html5 で追加された
section, svg? タグ等があるとエラーが出力されてしまう。
loadHTML 関数へ html4? で使用出来るタグを使用して引数へ渡した場合、
javascript タグの内容は CDATA として出力されるので魅力的。
removeChild 関数を利用してサクッ!と削除できる?( 削除まではテストしてない。 )

html5 で追加されたタグを使用した場合も javascript タグを削除の方向だったので、
DOMDocument クラスの loadXML 関数の引数へ HTML タグを渡してテスト。( 空タグは必ず "/" でタグを閉じる )
XML だから section, svg などのタグも問題なくツリー化してくれるけど、
javascript タグの内容は CDATA として出力してくれない。
javascript 内に "<", ">" などの記号がある場合エラーが出力されてしまう。
あああーっ!
HTML ドキュメントを一文字づつ読み込んでツリー化に挑戦!

テストした範囲で確認できた動作
1) template エリア に記述された xml を読み込んでツリー化。
2) javascript タグを CDATA へ変換後、 result エリアへ出力。
3) コメントを記述した場合エラー
4) CDATA を記述した場合エラー

結果、 無理に html5 タグを使用しないで、html4 のタグを使用、
PHP の loadHTML 関数を使用して javascript タグを削除でよさそな感じ。

■ htmlDomDocument.php


<?php

	class HTML extends DOMDocument
	{
		private $doc;
		function __construct($version="1.0",$encoding="utf-8")
		{
			$this->doc=new parent($version,$encoding);
		}
		
		public function saveHTML()
		{
			return $this->doc->saveXML();
		}
		
		public function loadHTML($contents,$option=0)
		{
			$this->setDomDocument($contents);
			/*
			$this->doc->loadHTML("<svg>a</svg>");
			$script=$this->doc->getElementsByTagName("script")->item(0)->nodeName;
			echo($script);
			$this->doc->loadXML($contents);
			*/
		}
		
		private function setDomDocument($contents)
		{
			$doc=$this->doc;
			//$doc->preserveWhiteSpace=true;
			$doc->formatOutput=true;
			$root=$doc->createElement("root");
			$root->setAttribute("xmlns","http://www.w3.org/1999/xhtml");
			$target=$doc->appendChild($root);
			$text="";
			$prev="\\";
			$type="text";
			$nodeName="";
			$attribute="";
			$cdata_quot="";
			foreach(str_split($contents) as $str)
			{
				switch($str)
				{
				
					case "<" :
							switch($type)
							{
								case "text" :
										if(strlen($text)!=0)
										{
											$target->appendChild($doc->createTextNode($text));
										}
										$type="tagS";
										$text="";
								break;
								
								case "cdata":
										$text.=$str;
								break;
								
								default :
										$text.=$str;
							}
					break;
					
					case ">" :
							switch($type)
							{
								case "tagS" :
										if(strlen(trim($text))!=0)
										{
											$nodeName=strtolower(trim($text));
											$target=$target->appendChild($doc->createElement($nodeName));
										}
										$type=($nodeName=="script") ? "cdata" : "text";
										$text="";
								break;
								
								case "tagE" :
										$target=$target->parentNode;
										$type="text";
										$text="";
								break;
								
								case "attribute" :
										if(strlen(trim($text))!=0)
										{
											$attr=trim($text);
											$target->setAttribute($attr,$attr);
										}
										$type=($nodeName=="script") ? "cdata" : "text";
										$text="";
								break;
								
								case "value" :
										$type=($nodeName=="script") ? "cdata" : "text";
										$text="";
								break;
								
								case "cdata" :
										if($cdata_quot==""&&preg_match("/[.]*<\/script$/si",$text))
										{
											$text=preg_replace("/<\/script$/si","",$text);
											$target->appendChild($doc->createCDATASection($text));
											$target=$target->parentNode;
											$type="text";
											$text="";
										}
										else
										{
											$text.=$str;
										}
								break;
								
								case "quot_double" :
										$text.=$str;
								break;
								
								case "quot_single" :
										$text.=$str;
								break;
								
								default :
										$type="text";
										$text.=$str;
							}
					break;
					
					case "/" :
							switch($type)
							{
								case "text" :
										$text.=$str;
								break;
								
								case "tagS" :
										if($prev!="<")
										{
											if(strlen(trim($text))!=0)
											{
												$nodeName=strtolower(trim($text));
												$target=$target->appendChild($doc->createElement($nodeName));
											}
										}
										else
										{
											$text.=$str;
										}
										$type="tagE";
								break;
								
								case "attribute" :
									$target=$target->parentNode;
									$type="value";
								break;
								
								case "cdata" :
										$text.=$str;
								break;
								
								default :
										$text.=$str;
							}
					break;
					
					case " " :
							switch($type)
							{
								case "tagS" :
										if(strlen(trim($text))!=0)
										{
											$nodeName=strtolower(trim($text));
											$target=$target->appendChild($doc->createElement($nodeName));
										}
										$type="attribute";
										$text="";
								break;
								
								case "attribute" :
										if(strlen(trim($text))!=0)
										{
											$attr=trim($text);
											$target->setAttribute($attr,$attr);
										}
										$text="";
								break;
								
								case "value" :
										$type="attribute";
								break;
								
								case "quot_double" :
										$text.=$str;
								break;
								
								case "quot_single" :
										$text.=$str;
								break;
								
								case "cdata" :
										$text.=$str;
								break;
								
								default :
										$text.=$str;
							}
					break;
					
					case "=" :
							switch($type)
							{
								case "attribute" :
										$attribute=trim($text);
										$type="value";
										$text="";
								break;
								
								case "cdata" :
										$text.=$str;
								break;
								
								default:
										$text.=$str;
							}
					break;
					
					case "\"" :
							switch($type)
							{
								case "value" :
										$type="quot_double";
								break;
								
								case "quot_double" :
										$target->setAttribute(trim($attribute),$text);
										$type="value";
										$text="";
								break;
								
								case "cdata" :
										switch($cdata_quot)
										{
											case "cdata_quot_double" :
													switch($prev)
													{
														case "\\" :
														
														break;
														
														default :
																$cdata_quot="";
													}
											break;
											
											case "cdata_quot_single" :
											
											break;
											
											default :
												$cdata_quot="cdata_quot_double";
										}
										$text.=$str;
								break;
								
								default :
										$text.=$str;
							}
					break;
					
					case "'" :
							switch($type)
							{
								case "value" :
										$type="quot_single";
								break;
								
								case "quot_single" :
										$target->setAttribute(trim($attribute),$text);
										$type="value";
										$text="";
								break;
								
								case "cdata" :
										switch($cdata_quot)
										{
											case "cdata_quot_single" :
													switch($prev)
													{
														case "\\" :
														
														break;
														
														default :
																$cdata_quot="";
													}
											
											break;
											
											case "cdata_quot_double" :
											
											break;
											
											default :
												$cdata_quot="cdata_quot_single";
										}
										$text.=$str;
								break;
								
								default :
										$text.=$str;
							}
					break;
					
					default:
							$text.=$str;
				}
				$prev=$str;
			}
			if(strlen($text)!=0)
			{
				$target->appendChild($doc->createTextNode($text));
			}
		}
	}

	if(isset($_POST["template"]))
	{
		$doc=new HTML("1.0","utf-8");
		$doc->loadHTML(rawurldecode($_POST["template"]));
		header("Content-type: text/xml");
		echo($doc->saveHTML());
	}
?>


今回は PHPを利用した csv ファイルのアップロードテスト。
参考にさせていただいたサイト。
■ [PHP] ファイルアップロードの上限サイズを変更する際にさわるディレクティブまとめ
■ ファイルのアップロード
■ PHP5 HTML フォームでアップロードファイルサイズの制限
■ テストサイト → PHP を利用した csv ファイルアップロードテスト(1)

プログラムの流れ

  1. 選択ボタンで csv ファイルを選択
  2. upload ボタンで csv ファイルをサーバーへアップロード
  3. アップロードされた csv ファイルを fgetcsv 関数を使用して配列として取得。
  4. 取得した配列の値から HTML の table タグを使用して表を出力。
  5. アップロードした csv ファイルは HTML タグ出力後削除。

■ プログラム実行結果

csv アップロードテスト実行結果

プログラムの制限と注意事項

  1. アップロードできるファイルサイズの上限は 100KB
  2. 上限を超えたファイルをアップロードするとエラー表示。
  3. csv ファイルの区切りはカンマのみ
  4. 取得した配列の値から HTML の table タグを使用して表を出力。

csv ファイルのアップロードサイズの上限は .htaccess で設定。
.htaccess ファイルへ次の二行を追加。
php_value post_max_size 100000bytes
php_value upload_max_filesize 100000bytes
上記、二行を追加してアップローロファイルへ上限の設定は出来けど、
ローカル( xampp ) で上限を超えたファイルをアップロードした場合にエラーが出力される。
このエラーを回避するの方法がわからない。

■ Warning


Warning: POST Content-Length of 307042 bytes exceeds the limit of 100000 bytes in Unknown on line 0

■ upload.php


<?php
	function putFile()
	{
		$fileName="";
		$message="";
		if(is_uploaded_file(@$_FILES["uploadFile"]["tmp_name"]))
		{
			$uploadFile=$_FILES["uploadFile"]["name"];
			$check=explode(".",$uploadFile);
			if(count($check)==2&&$check[count($check)-1]=="csv")
			{
				$fileName="tmp/".$uploadFile;
				if(move_uploaded_file($_FILES["uploadFile"]["tmp_name"],$fileName))
				{
					chmod($fileName,0644);
				}
				else
				{
					$message="ファイルアップロードに失敗しました";
				}
			}
			else
			{
				$message="拡張子が csv 以外の可能性があります。";
			}
		}
		else
		{
			$message="ファイルサイズが 100KB より大きいファイルの選択、<br>又はファイルが選択されていない可能性があります。";
		}
		return array("fileName"=>$fileName,"message"=>$message);
	}
	$result=putFile();
	if($result["message"]=="")
	{
		$fp=fopen($result["fileName"],"r");
		if($fp)
		{
			if(flock($fp,LOCK_EX))
			{
				$table="<table style=\"background-color:#333;width:auto;height:auto;\"><tbody>";
				while($line=fgetcsv($fp))
				{
					$table.="<tr>";
					for($i=0;$i<count($line);$i++)
					{
						$str=htmlspecialchars(trim($line[$i]),ENT_QUOTES);
						$str=str_replace(array("\r\n","\n"),"<br>",$str);
						$table.="<td style=\"vertical-align:top;padding:1px;background-color:#fff;\"><p style=\"white-space:nowrap;width:auto;height:auto;\">".$str."</p></td>";
					}
					$table.="</tr>";
				}
				$table.="</tbody></table>";
				echo($table);
				flock($fp,LOCK_UN);
			}
			fclose($fp);
			if(file_exists($result["fileName"]))
			{
				unlink($result["fileName"]);
			}
		}
	}
	else
	{
		echo("<p>".$result["message"]."</p>\n");
	}
?>

今回は yahoo の急上昇ワード デイリーの取得テスト。
テストサイト → 急上昇ワード デイリー - Yahoo!検索データ取得テスト(1)
前回やった google 急上昇ワードは、 simplexml_load_file 関数と、
simple_load_string を使用して xml ファイルの値を取得。
今回は、同じく xml 値をツリー化して取得出来る new DomDocument クラス?を使用して、
xml 値の取得テスト。
yahoo の急上昇ワードデイリーのは "http://searchranking.yahoo.co.jp/rss/burst_ranking-rss.xml"
xml 形式で格納されてる。
new DomDocument の load 関数で xml をツリー化して値を格納。
あとは、 getElementsByTagName 関数でタグに格納されている値を取得。


<?php
	$url="http://searchranking.yahoo.co.jp/rss/burst_ranking-rss.xml";
	$doc=new DomDocument;
	$flg=@$doc->load($url);
	if($flg)
	{
		$root=$doc->documentElement;
		$channel=$root->getElementsByTagName("channel")->item(0);
		$title=$channel->getElementsByTagName("title")->item(0)->firstChild->nodeValue;
		$link=$channel->getElementsByTagName("link")->item(0)->firstChild->nodeValue;
		$lastBuildDate=$channel->getElementsByTagName("lastBuildDate")->item(0)->firstChild->nodeValue;
		$flg=preg_match("/[a-zA-Z]+, [0-9]+ [a-zA-Z]+ [0-9]{4} [0-9]{2}:[0-9]{2}:[0-9]{2}/",$lastBuildDate,$match);
		echo("<div id=\"caption\">");
		echo("<a href=\"".$link."\" target=\"_top\">".$title."</a><br>");
		echo("<span style=\"font-size:80%\">lastBuildDate:[ ".$match[0]." ]</span>");
		echo("</div>");
		$items=$channel->getElementsByTagName("item");
		echo("<ol>\n");
		for($i=0;$i<$items->length;$i++)
		{
			$item=$items->item($i);
			$title=$item->getElementsByTagName("title")->item(0)->firstChild->nodeValue;
			$href=$item->getElementsByTagName("link")->item(0)->firstChild->nodeValue;
			$description=$item->getElementsByTagName("description")->item(0)->firstChild->nodeValue;
			echo("<li>[ ".$description." ]<br><a href=\"".$href."\" target=\"_top\">".$title."</a></li>\n");
		}
		echo("</ol>\n");
	}
	unset($doc);
?>

■ PHPを利用した Yahoo 急上昇ワード取得


# スポンサードリンク