Never been to CodeSnippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

Removing <?xml version="1.0"?> from the output of XSLTProcessor->transformToXml()

Just add this as a top level element in your XSL document.

<xsl:output method="html" />


Thanks to this post on php.net for the answer:
http://us3.php.net/manual/en/xsltprocessor.transformtoxml.php#80887

Super simple XML and PHP

This is a super simple implementation of a concept found here:
http://xtech06.usefulinc.com/schedule/paper/19

This xml class provides a very simple way to open an XML file, get information from the XML file, modify information from the XML file and save the XML file. It also supports automatic creation of new XML files based on an automatically incrementing ID senerio (similar to auto incrementing primary keys in databases).

The creation of new XML files is done by looking for a "template" xml file named 0.xml in the directory passed to the create function. If the template file is found, then it is loaded into the xml class and saved to a new file whose name is one more than the highest filename (of course the xml extension is added on). Eventually, I will try and add some validation code and whatever else, but for now I'm trying to keep things simple.

This requires the DOM module to be built into PHP.
I am using PHP 5.

If anyone has any ideas on how to improve this, feel free to post comments.

<?php

class xml
{
	var $dom;
	var $uri;

	function xml($uri)
	{
		$this->dom = new DOMDocument();

		if(preg_match('/\.xml$/', $uri))
		{
			$this->uri = $uri;
		}
		else
		{
			$this->uri = $this->create($uri);
		}
		$this->dom->load($this->uri);
	}

	function set($query, $value)
	{
		$path = new DOMXPath($this->dom);
		$nodes = $path->query($query);
		$nodes->item(0)->nodeValue = $value;
	}

	function get($query)
	{
		$path = new DOMXPath($this->dom);
		$nodes = $path->query($query);
		return $nodes->item(0)->nodeValue;
	}

	function save()
	{
		$this->dom->save($this->uri);
	}

	function create($uri)
	{
		// Build the URI of the template file.
		$template = sprintf('%s/0.xml', $uri);

		// If the directory doesn't exist, we can't really
		// do anything.
		if(!is_dir($uri))
		{
			exit('No directory');
		}

		// If the template file doesn't exist, we cannot
		// create a new file automatically.
		if(!file_exists($template))
		{
			exit('No template');
		}

		// Load the template XML into our DOMDocument.
		$this->dom->load($template);

		// Scan the directory into an array.
		$dir = scandir($uri);

		// Pull out the highest ID
		$id = str_replace('.xml', '', array_pop($dir));

		// Add one to it
		$id++;

		// Construct the new path with the new ID
		$uri = sprintf('%s/%s.xml', $uri, $id);

		// Save the new file
		$this->dom->save($uri);

		// Return the URI of the new XML file.
		return $uri;
	}
}

// The following code will create a new XML file
// under the directory /var/www/data/users.
$x = new xml('/var/www/data/users');
$x->set('//user/name', 'John Doe');
$x->save();

?>

算術演算子

演算子:機能
+:足し算、正の符号、ストリングの連結
%:割り算のあまり(剰余)
%=:余りを代入

"":ストリングを囲む
'':これもストリングを囲む('と"を入れ子で使うと、そのまま表示される)

!:否定(trueのときfalse、falseのときtrue)
~:ビット単位の否定
<<:ビット単位の左へシフト
>>:ビット単位の右へシフト

trace("これは'Test1'です");
//出力:これは'Test1'です

trace('これは"test2"です');
//出力:これは"Test2"です



XML演算子
@:XMLまたはXMLListのアトリビュートにアクセスする
{}:XMLまたはXMLListの式で変数を囲む
[]:XMLまたはXMLListのプロパティ(ノード)にアクセスする
+:XMLまたはXMLListの値の連結
+=:XMLまたはXMLListの値を連結して代入
..:XMLまたはXMLListのプロパティ名、アトリビュート名での検索抽出
.:XMLまたはXMLListの子エレメント、または、アトリビュートにアクセスする
():XMLまたはXMLListの構造内の式を評価・実行
<>:XMLのタグを定義する
delete:XMLエレメントまたはアトリビュートを削除する

var goodsXml:XML = 
<goods>
  <cap id = "t102">
    <size>S</size>
    <top-color>red</top-color>
  </cap>
  <cap id = "t105">
    <size>M</size>
    <top-color>blue</top-color>
  </cap>
</goods>;

var myCap:XML = goodsXml.cap[0];

trace(myCap.@id);
//出力:t102
trace(myCap.size);
//出力:S
trace(myCap["top-color"]);
//出力:red
//エレメントとの名前に"-"が含まれているので、.演算子ではアクセスできない

Mozilla export coordinates to a .kml file (for Google Earth)

Usage:
// define a location hash:
var location = {
    'name':'Tokyo',
    'latitude':35.65444,
    'longitude':139.74472
    // Other data: 
    //'heading' : 0 ,
    //'tilt' : 0 ,
    //'range':  1000000 
}
// choose a name for your .kml file:
var myFileName = 'my_geo.kml';

// now use them to force opening a .kml file:
$google.openKMLFile(location,myFileName);

Will output:
<?xml version="1.0" encoding="UTF-8" ?> 
<kml xmlns="http://earth.google.com/kml/2.0">
<Document>
<Placemark>
<name>Tokyo</name> 
<Point>
<altitudeMode>relativeToGround</altitudeMode> 
<coordinates>139.74472,35.65444,0</coordinates> 
</Point>
<LookAt>
<heading>0</heading> 
<tilt>0</tilt> 
<range>1000000</range> 
<latitude>35.65444</latitude> 
<longitude>139.74472</longitude> 
</LookAt>
</Placemark>
</Document>
</kml>


Helper library :
var $google = { 
	
	_exampleLocation : { 
		'name':'Tokyo',
		'latitude':35.65444,
		'longitude':139.74472
		// Other data: 
		//'heading' : 0 ,
		//'tilt' : 0 ,
		//'range':  1000000 
	},
	
	_CC : Components.classes,
	
	_CI : Components.interfaces,
	
	_getDOMImpl : function(){
		if (this._domImpl == null){
			this._domImpl = this._CC["@mozilla.org/xmlextras/domparser;1"].createInstance(this._CI.nsIDOMParser).parseFromString("<foo/>", "text/xml").implementation;
		}
		return this._domImpl;
	},
	
	_stringToTmpFile: function(dataString, charset, tmpFileName) {
		var unicodeConverter = this._CC["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(this._CI.nsIScriptableUnicodeConverter);
		unicodeConverter.charset = charset;
		var convertedString = unicodeConverter.ConvertFromUnicode(dataString);
				
		var tmpFile = this._CC["@mozilla.org/file/directory_service;1"].getService(this._CI.nsIProperties).get("TmpD", this._CI.nsILocalFile);
									 
		tmpFile.append(tmpFileName);
		tmpFile.createUnique(this._CI.nsIFile.NORMAL_FILE_TYPE, 0664);
	
		var outStream = this._CC["@mozilla.org/network/file-output-stream;1"].createInstance(this._CI.nsIFileOutputStream);

		outStream.init(tmpFile, 0x02 | 0x08 | 0x20, 0664, 0);
		outStream.write(convertedString, convertedString.length);
				
		var finalData = unicodeConverter.Finish();
		if (finalData.length > 0) {
			outStream.write(finalData, finalData.length);
		}
		outStream.close(); 
		
		return tmpFile ; 
	},
	
	openKMLFile : function(location,fileName) {
		
		if (!location || location == '') {  location = this._exampleLocation ; }
			
		var doc = this._getDOMImpl().createDocument("http://earth.google.com/kml/2.0", "kml", null);
				
		var kmlDocument = doc.createElement("Document");
		doc.documentElement.appendChild(kmlDocument);
		
		var kmlPlacemark = doc.createElement("Placemark")
		kmlDocument.appendChild(kmlPlacemark);
		
		var kmlName = doc.createElement("name");
		kmlPlacemark.appendChild(kmlName);	
		
		var kmlPoint = doc.createElement("Point");
		kmlPlacemark.appendChild(kmlPoint);

		var kmlAltitudeMode = doc.createElement("altitudeMode");
		kmlPoint.appendChild(kmlAltitudeMode);
		
		var kmlCoordinates = doc.createElement("coordinates");
		kmlPoint.appendChild(kmlCoordinates);
		
		var kmlLookAt = doc.createElement("LookAt");
		kmlPlacemark.appendChild(kmlLookAt);

		var kmlHeading = doc.createElement("heading");
		kmlLookAt.appendChild(kmlHeading);

		var kmlTilt = doc.createElement("tilt");
		kmlLookAt.appendChild(kmlTilt);
		
		var kmlRange = doc.createElement("range");
		kmlLookAt.appendChild(kmlRange);
		
		var kmlLatitude = doc.createElement("latitude");
		kmlLookAt.appendChild(kmlLatitude);
		
		var kmlLongitude = doc.createElement("longitude");
		kmlLookAt.appendChild(kmlLongitude);
	
		kmlName.appendChild(doc.createTextNode(location.name));
		kmlAltitudeMode.appendChild(doc.createTextNode("relativeToGround"));
		kmlCoordinates.appendChild(doc.createTextNode(location.longitude + "," + location.latitude + ",0"));	
		kmlHeading.appendChild(doc.createTextNode(location.heading ? location.heading : '0'));
		kmlTilt.appendChild(doc.createTextNode(location.tilt ? location.tilt : '0'));
		kmlRange.appendChild(doc.createTextNode(location.range ? location.range : '1000000'));
		kmlLatitude.appendChild(doc.createTextNode(location.latitude));
		kmlLongitude.appendChild(doc.createTextNode(location.longitude));		
		
		var serializer = this._CC["@mozilla.org/xmlextras/xmlserializer;1"].createInstance(this._CI.nsIDOMSerializer);
		var kmlString = '<?xml version="1.0" encoding="UTF-8"?>' + serializer.serializeToString(doc);

		var kmlFile = this._stringToTmpFile(kmlString, "UTF-8", fileName);
		kmlFile.launch();
		
	}
	
}

Groovy XML Schema Validator

// Create a Schema and a sample document, then validate the document against the schema

def xsd = '''
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="comics">
</xs:element>
</xs:schema>
'''

def xml = '''
<comics>
</comics>
'''

import javax.xml.XMLConstants
import javax.xml.transform.stream.StreamSource
import javax.xml.validation.SchemaFactory

def factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
def schema = factory.newSchema(new StreamSource(new StringReader(xsd)))
def validator = schema.newValidator()
validator.validate(new StreamSource(new StringReader(xml)))

Groovy XML Schema Validator

// Create a Schema and a sample document, then validate the document against the schema

def xsd = '''
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="comics">
</xs:element>
</xs:schema>
'''

def xml = '''
<comics>
</comics>
'''

import javax.xml.XMLConstants
import javax.xml.transform.stream.StreamSource
import javax.xml.validation.SchemaFactory

def factory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI)
def schema = factory.newSchema(new StreamSource(new StringReader(xsd)))
def validator = schema.newValidator()
validator.validate(new StreamSource(new StringReader(xml)))

simple Ruby RSS reader

// fetch & parse RSS into an object

require 'rss/2.0'
require 'open-uri'

class RssReader

  def parseFeed (url, length)
    feed_url = url
    output = "";
    open(feed_url) do |http|
      response = http.read
      result = RSS::Parser.parse(response, false)
      output = "<span class=\"feedTitle\">#{result.channel.title}</span><br /><ul>" 
      result.items.each_with_index do |item, i|
        output += "<li><a href=\"#{item.link}\">#{item.title}</a></li>" if ++i < length  
      end 
      output += "</ul>" 
    end
    return output
  end

end

Example using xmlplarser's saxdriver to parse huge files

// description of your code here

#!/usr/bin/evn ruby
## to run this you call run_amazon_import(datafile) with dataflie = a file to open for parsing, which later is opened based on:
## ("#{RAILS_ROOT}/data/" + datafile + ".xml")
## This is hard coded to look at Item elements, and in this example
## parses out the ASIN as @@product_id and ItemAttributes/Title as @@name
## see check_position_space(name,ch)

require 'xml/saxdriver'
@flag_item  = false

  @@finaldata = []
  @@vars = []
  @@positionSpace = []
  @@currentName = []
def reset_vals
  @@product_id = nil
  @@name = nil
end
def check_position_space(name,ch)
  # with each value within item we check to see if the
  # @@positionSpace (a concatenation of each value's name
  # equals the value we are looking for, if so put it in a global 
  # variable
  if @@positionSpace == 'ASIN'
    @@product_id =  ch
  elsif @@positionSpace == 'ItemAttributesTitle'
  	# if I did this again, I would name @@positionSpace
  	# with / between names in startElement so it would be simlar to other 
  	# ruby xml naming schems so:
  	# @@positionSpace == 'ItemAttributesTitle' would be:
  	# @@positionSpace == 'ItemAttributes/Title'
  	@@name = ch
  end
end

class TestHandler < XML::SAX::HandlerBase
  attr_accessor :data
  def startDocument
    @@data = []
  end
  def startElement(name, attr)
    @flag_item = true if name == 'Item'
    @@positionSpace = '' if name == 'Item'
    if @flag_item == true and name != 'Item'
        @@positionSpace = @@positionSpace + name
    elsif name == 'Item'
      reset_vals
    end
    @@currentName = name
  end
  def endElement(name)
    if @flag_item == true and name != 'Item'
        lenName = name.length
        @@positionSpace = @@positionSpace[0, @@positionSpace.length - lenName]
    end
    if name == 'Item'
      @@finaldata  << @@data.to_s
      @@data = []
	  ## Here I would have a fully parsed Item and do something with it
    end
    @flag_item = false if name == 'Item'
  end
  def characters(ch, start, length)
    check_position_space(@@currentName, ch[start, length])
  end
end

def run_amazon_import(datafile)
  @@datafile = datafile
  p = XML::SAX::Helpers::ParserFactory.makeParser("XML::Parser::SAXDriver")
  h = TestHandler.new
  p.setDocumentHandler(h)
  p.setDTDHandler(h)
  p.setEntityResolver(h)
  p.setErrorHandler(h)

  begin
    p.parse("#{RAILS_ROOT}/data/" + datafile + ".xml")
  rescue XML::SAX::SAXParseException
    p(["ParseError", $!.getSystemId, $!.getLineNumber, $!.getMessage])
  end
end

xml to objects

Доступ к дереву XML как к обычным объектам

Для этого можно использовать XSD::Mapping из стандартной библиотеки:

requirexsd/mapping’ 
people = XSD::Mapping.xml2obj(File.read("people.xml")) 
people.person[2].name # => "name3" 


Если в имени тэга присутствует дефис, можно сделать так: people[’foo-bar’]

Ну а выполнить обратное преобразование объектного дерева в XML поможет метод: XSD::Mapping.obj2xml


Somewhat ridiculous XML parser + image generator

Seriously needs caching. SRSLY

<?php
	class ImageGeneration {
		function getInfo($name) {
			$this->loadDefaultInfo();
			$XML = new XMLReader;
			$XML->open("http://chat.hypermutt.net/online/user/".$name.".xml");
			$wn = array();

			while($XML->read()) {
				if ($XML->nodeType == XMLReader::ELEMENT) {
					$wn[] = $XML->name;
				}
				if ($XML->nodeType == XMLReader::TEXT) {
					if ("user/info/nick" == implode('/', $wn)) {
						$this->name = $XML->value . ". ";
					}
					if ("user/info/online" == implode('/', $wn)) {
						$this->away = ($XML->value == "TRUE") ? true : false;
					}


					if ("user/info/connected" == implode('/', $wn)) {
						$this->onlinefor = strtotime($XML->value);
					}
					if ("user/info/timenow" == implode('/', $wn)) {
						$sc = (strtotime($XML->value) - $this->onlinefor);
						$t = floor($sc/86400);
							$c["days"] = ($t > 0) ? $t."D " : ""; $sc = ($sc-$t*86400);
						$t = floor($sc/3600);
							$c["hours"] = ($t > 0) ? $t."H " : ""; $sc = ($sc-$t*3600);
						$t = floor($sc/60);
							$c["minutes"] = ($t > 0) ? $t."M " : "";
						$this->onlinefor = $c["days"].$c["hours"].$c["minutes"];
					}
					

					if ("user/info/away" == implode('/', $wn)) {
						$this->away = ($XML->value == "TRUE") ? true : false;
					}
					if ("user/info/awaymsg" == implode('/', $wn)) {
						$this->awaymessage = $XML->value;
					}
					if ("user/channels/channel/name" == implode('/', $wn)) {
						$this->channels .= str_replace('#','',$XML->value)." ";
					}
				}
				if ($XML->nodeType == XMLReader::END_ELEMENT) {
					array_pop($wn);
				}
			}
			$XML->close();
		}
		
		function loadDefaultInfo() {
			$this->name = ". ";
			$this->online = true;
			$this->onlinefor = "";
			$this->away = true;
			$this->awaymessage = "";
			$this->channels = "";
		}
	
		function drawImage() {
			header("Content-type: image/png");
			$image = imagecreatefrompng("background.png");
				$white = imagecolorallocate($image, 255, 255, 255);
				$red   = imagecolorallocate($image, 255, 0, 0);
				$green = imagecolorallocate($image, 0, 255, 0);
				$feb = "slkscreb.ttf";
				$fnn = "slkscr.ttf";
			
			$sizes["name"]   = imagettfbbox(6, 0, $feb, $this->name);
			$sizes["online"] = imagettfbbox(6, 0, $feb, "online: ");
			$sizes["away"]   = imagettfbbox(6, 0, $feb, "away: ");
			$sizes["yes"]    = imagettfbbox(6, 0, $feb, "yes ");
			$sizes["#"]     = imagettfbbox(6, 0, $feb, "#: ");
			
			imagettftext($image, 6, 0, 22, 8, -$white, $feb, $this->name);
			imagettftext($image, 6, 0, (22 + $sizes["name"][4]), 8, -$white, $feb, "online:");
			imagettftext($image, 6, 0, (22 + $sizes["name"][4] + ($sizes["online"][4] - $sizes["away"][4])), 18, -$white, $feb, "away:");
			imagettftext($image, 6, 0, (22 + $sizes["name"][4] + ($sizes["online"][4] - $sizes["#"][4])),    28, -$white, $feb, "#: ");
			
			imagettftext($image, 6, 0, (22 + $sizes["name"][4] + $sizes["online"][4]),  8, -(($this->online) ? $green : $red), $feb, (($this->online) ? "yes" : "no"));
			imagettftext($image, 6, 0, (22 + $sizes["name"][4] + $sizes["online"][4]), 18, -((!$this->away)  ? $green : $red), $feb, (($this->away)   ? "yes" : "no"));
			
			if ($this->online)
				imagettftext($image, 6, 0, (22 + $sizes["name"][4] + $sizes["online"][4] + $sizes["yes"][4]),  8, $white, $fnn, $this->onlinefor);
			if ($this->away)
				imagettftext($image, 6, 0, (22 + $sizes["name"][4] + $sizes["online"][4] + $sizes["yes"][4]), 18, $white, $fnn, $this->awaymessage);
			imagettftext($image, 6, 0, (22 + $sizes["name"][4] + $sizes["online"][4]), 28, $white, $fnn, $this->channels);
			
			imagepng($image);
			imagedestroy($image);
		}
	}
	
	$x = new ImageGeneration;
	$x->getInfo($_GET['name']);
	$x->drawImage();
?>