'eclipse' 카테고리의 다른 글
Eclipse Tip (0) | 2008.09.08 |
---|---|
JUnit 관련 사이트 (0) | 2008.09.02 |
Eclipse 관련 IBM developerworks (0) | 2008.09.02 |
Eclipse PlugIn (0) | 2008.08.29 |
이클립스 가니메데 - IBM developerworks (0) | 2008.07.28 |
Eclipse Tip (0) | 2008.09.08 |
---|---|
JUnit 관련 사이트 (0) | 2008.09.02 |
Eclipse 관련 IBM developerworks (0) | 2008.09.02 |
Eclipse PlugIn (0) | 2008.08.29 |
이클립스 가니메데 - IBM developerworks (0) | 2008.07.28 |
#include <string.h>
int memcmp(const void *s1, const void *s2, size_t n);
#include <string.h>#include <unistd.h>#include <stdio.h>
typedef struct __person{int age;char name[12];} person;
int main(){person a, b;int state;
a.age = 28;strncmp(a.name, "yundream", 11);
b.age = 24;strncmp(a.name, "gim", 11);
// a 와 b 의 처음 8 바이트를 비교한다.state = memcmp((void *)&a, (void *)&b, 8);if (state < 0){printf("b older than a\n");}else if(state == 0){printf("same same\n");}elseprintf("a older than b\n");
return 0;}
C 프로그램 지역변수.전역변수.정적변수 외부변수 (0) | 2009.03.03 |
---|---|
gcc 컴파일 옵션 (0) | 2008.07.16 |
make (0) | 2008.06.04 |
[함수] sprintf - 출력 (0) | 2008.05.16 |
[함수] memcpy - 메모리카피 (0) | 2008.05.16 |
A | B | C | |
1 | 목록1 | 목록2 | 값 |
2 | 가 | 1 | a |
3 | 나 | 2 | b |
4 | 다 | 3 | c |
5 | 라 | 4 | d |
6 | 마 | 5 | e |
7 | 바 | 6 | f |
8 | 사 | 7 | g |
9 | 아 | 8 | h |
10 | 아 | 9 | i |
11 | 사 | 10 | j |
12 | 바 | 11 | k |
13 | 마 | 12 | l |
14 | 라 | 13 | m |
15 | 다 | 14 | n |
16 | 나 | 15 | o |
17 | 가 | 16 | p |
위와 같은 목록에서
=VLOOKUP("아",$A$1:$C$17,3,FALSE)
를 하면 값은 h 가 출력됩니다.
하지만 값 열의 i의 값을 불러올 수는 없습니다.
하지만 목록1과 목록2에서 조건을 주어 값 열의 데이터를 원하는 것으로
불러올 수는 있습니다
목록1 | 목록2 | 값 |
가 | 1 | a |
가 | 16 | p |
a 와 p의 값의 수식은
=INDIRECT("C"&SUMPRODUCT(($B$2:$B$17=F2)*($C$2:$C$17=G2)*(ROW($D$2:$D$17))))
와
=INDIRECT("C"&SUMPRODUCT(($B$2:$B$17=F3)*($C$2:$C$17=G3)*(ROW($D$2:$D$17))))
입니다
여기서 수식 설명입니다
SUMPRODUCT(($B$2:$B$17=F3)*($C$2:$C$17=G3)*(ROW($D$2:$D$17)))
에서
$B$2:$B$17=F2 는 "가" 일 때만
1의 값을 나머지는 0의 값을 가집니다
$C$2:$C$17=G2 는 1 일 때만 1의 값을 가지고 나머지는 0을 가집니다
($B$2:$B$17=F2)*($C$2:$C$17=G2)
의 값은
1 | 1 | 1 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
0 | 0 | 0 |
1 | 0 | 0 |
에서 2번째 열의 값으로 배열형태를 취합니다
ROW($C$2:$C$17)
는 각각의 셀의 행번호이고
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
의 값으로 배열의 형태를 취합니다
여기서
sumproduct 함수의 값은
위의 두 수식에서
각각 2와 17을 가집니다
그리고
마지막으로 indirect 함수를 적용합니다
c 열에서 값을 불러오므로
=Indirect("C"&
까지 해서 열의 값을 지정하고 행의 값은 위의 Sumproduct 함수의 결과값으로 지정하면
위의 수식은 각각
=Indirect("C2")
=Indirect("C17")
이 됩니다
최종적으로
첫번째 수식=a
두번째 수식=p
의 값을 출력합니다
사용자 정의 함수 사용하기 (0) | 2008.11.11 |
---|---|
[함수]문자열자르기 - SEARCH (0) | 2008.11.11 |
[함수]파일 및 시트명 (0) | 2008.09.30 |
[함수]엑셀함수 (0) | 2008.09.30 |
[함수]indirect - 문자열을 참조로 사용할 때 (0) | 2008.09.25 |
=REPLACE(CELL("filename",A1),1,FIND("]",CELL("filename",A1)),"")
=DATE(YEAR(TODAY()),MONTH(TODAY()),REPLACE(CELL("filename",A1),1,FIND("]",CELL("filename",A1)),""))
=MID(CELL("filename"),FIND("[",CELL("filename"))+1,FIND("]",CELL("filename"))-FIND("[",CELL("filename"))-5)
=HYPERLINK(CONCATENATE(MID(CELL("filename"),FIND("[",CELL("filename")),FIND("]",CELL("filename"))-FIND("[",CELL("filename"))+1), K2, "!a8"),K2)
CHAR(10)
Sub SheetsSort()Dim i As IntegerDim j As IntegerDim intCount As IntegerDim varTempDim strName() As StringintCount = Sheets.CountReDim strName(intCount)For i = intCount To 1 Step -1strName(i) = Sheets(i).NameNext iFor i = UBound(strName()) - 1 To LBound(strName()) Step -1For j = 1 To iIf strName(j) > strName(j + 1) ThenvarTemp = strName(j)strName(j) = strName(j + 1)strName(j + 1) = varTempSheets(varTemp).Move after:=Sheets(strName(j))End IfNext jNext iSheet1.ActivateEnd Sub
[함수]문자열자르기 - SEARCH (0) | 2008.11.11 |
---|---|
[함수]중복된 목록에서 데이터 불러오기 (0) | 2008.10.02 |
[함수]엑셀함수 (0) | 2008.09.30 |
[함수]indirect - 문자열을 참조로 사용할 때 (0) | 2008.09.25 |
[메크로]레이아웃 컨트롤 (0) | 2008.08.06 |
[함수]문자열자르기 - SEARCH (0) | 2008.11.11 |
---|---|
[함수]중복된 목록에서 데이터 불러오기 (0) | 2008.10.02 |
[함수]파일 및 시트명 (0) | 2008.09.30 |
[함수]indirect - 문자열을 참조로 사용할 때 (0) | 2008.09.25 |
[메크로]레이아웃 컨트롤 (0) | 2008.08.06 |
* ROW MAI KOEY JA RUK GUN MEE TAE WUN TEE AUN WAI
PAAN LEREI PAI LAE MAI KOEY JA GLUB MAH
PEN KAE KWARM PRA TUP JAI TEE YOUNG KONG NAN NAH
MEE TAE FON MEE TAE FAR TEE KOW JAI
** TAI TON MAI TEE MAI MEE ROM NGOW
GING GARN MUN MAI DAI SOONG SUK TOW RAI
TAE RARK LEUK LONG NAI DIN YOUNG LEUK LONG NAI JAI
MEE KWARM MAI TEE MARK MAI TA LAUD MAH
YOUNG RARK LEUK LONG NAI DIN YOUNG LEUK LONG NAI JAI
MEE KWARM MAI TEE MARK MAI…TA LAUD MAH
Another Sad Song - Jasmin Tabatabai (0) | 2009.01.20 |
---|---|
Blower's daughter - Damien Rice (0) | 2009.01.20 |
Falling Slowly - Glen Hansard (0) | 2009.01.19 |
If You Want Me - Marketa Irglova (0) | 2009.01.19 |
Tony Takitani - Ryuichi Sakamoto (0) | 2005.10.16 |
=indirect(a1 & b1 & "!f1")
[함수]문자열자르기 - SEARCH (0) | 2008.11.11 |
---|---|
[함수]중복된 목록에서 데이터 불러오기 (0) | 2008.10.02 |
[함수]파일 및 시트명 (0) | 2008.09.30 |
[함수]엑셀함수 (0) | 2008.09.30 |
[메크로]레이아웃 컨트롤 (0) | 2008.08.06 |
Rollei35수리점 (0) | 2009.10.11 |
---|---|
필름 & 현상소 (0) | 2009.01.22 |
http://iilii.egloos.com/3788564
1. iterator 패턴은..
프로그래밍을 하다 보면, array나 List, Set, Map과 같은 애들을 많이 씁니다. 얘네들의 특징은 어떤 데이터들의 집합체라는 겁니다. 원래 집합체란 게 속에 뭐가 들었냐가 중요하죠. 그래서 집합체들을 다룰 때는 얘들이 가지고 있는 개별 원소에 대해서 이런 저런 작업들을 할 일이 많습니다.
iterator를 쓰게 되면, 집합체와 개별 원소들간에 분리시켜 생각할 수가 있습니다. 심지어는 그 집합체가 어떤 클래스의 인스턴스인지 조차 신경쓰지 않아도 됩니다.
2. 예제
package c01_iterator;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;public class MagicianList implements Iterable<String> {
private List<String> list = new ArrayList<String>();public void add(String name){
list.add(name);
}public Iterator<String> iterator() {
return new Iterator<String>(){
int seq = 0;
public boolean hasNext() {
return seq < list.size();
}
public String next() {
return list.get(seq++);
}
public void remove() {
}
};
}public static void main(String[] arg){
MagicianList magicians = new MagicianList();
magicians.add("이은결");
magicians.add("Kevin parker");
magicians.add("David Blaine");Iterator<String> iterator = magicians.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
System.out.println(element);
}
}
}
먼저, main 함수의 황토색 부분을 보면, magicians 의 원소들을 뽑아내는데, magicians 라는 변수를 전혀 쓰지 않습니다. 물론, 내부적으로 iterator라는 변수가 magicians와 관계를 유지해주고 있긴합니다만, 일단 iterator를 가지고 온 후에는 데이터 집합체가 뭐냐에 신경을 쓸 필요가 없어진 거죠. iterator만 가져오면, 걍 hasNext() , next() 만 가지고 반복하면서 원소들에 대해서 처리를 하면 됩니다.
3. Iterator관련 interface
소스 코드의 보라색 부분이 jdk 안에 있는 Iterator에 관한 부분입니다.
java.util.Iterable 이란 넘을 구현하고 있습니다. 고놈한테는 Iterator<E> iterator() 라는 메소드 한개만 있습니다. 뭔소리냐면, 이 클래스는 무슨무슨 집합체 데이터를 가꾸 있으니깐, iterator로 원소들을 뽑아다가 쓸 수 있도록 제공하겠다는거죠.
그담에 등장하는 것이 java.util.Iterator입니다. 소스 코드의 청록색 부분입니다.
method가 3개가 있죠? hasNext()는 다음 구성 요소가 있냐고 물어봅니다. next()는 그 요소를 뽑아옵니다. remove()는 일부러 구현을 안했습니다. API에 보면, 마지막으로 꺼낸 요소를 제거한다.(optional operation) 이라고 되어있습니다. optional이라는 걸 강조할라고 구현 안했습니다. 그리고 iterator를 돌면서 데이터를 삭제한다는 것은 그다지 바람직해 보이진 않습니다.
요기서 한가지 집고 넘어가야 할 것은 시퀀스는 hasNext()가 아니라 next()에서 증가시켜야 한다는 것입니다. 좀 비상식적인 얘기긴 합니다만, hasNext()를 호출하고 또 호출하는 일이 발생할 수도 있기 때문이죠. hasNext라는 메소드 이름이, next를 가지고 있는지를 체크하겠다는 것이니까요.
4. JAVA API에 있는 Iterator
우리가 알고 있는 일반적인 집합체들은 전부 Iterator를 제공합니다. Set, List 등은 Collection 을 상속 받는데, Collection이 Iteratable을 상속 받기 때문입니다.
위에서 청록색 부분을 list.iterator() 라고 쭐여버려도 됩니다. 걍 있는 거 안 쓰고 굳이 구현한 건 예제 파일을 함 보여줄라고 한 겁니다. 사실은 예제 전체가 억지로 만들어낸 겁니다. 일반적인 집합체를 구현해서 쓰는 일은 거의 없고, JDK 안에 들어 있는 애들을 가져다 쓰는데, 걔들은 거의 대부분 Iterator를 제공하거든요.(Map은 한 다리 건너서 제공합니다.) 그래서 Iterator를 직접 구현할 일은 거의 없습니다. 가져다가 쓸 일이 있을 뿐이죠.
이제 Map은 왜 Iterator를 제공하지 않는 지를 살펴보죠. Map은 Set이나 List와는 달리 key-value의 구조입니다. key에 대한 Iterator인지 value에 대한 Iterator인지 구별할 방법이 없죠. 그래서 아예 제공을 안 합니다. 그러나 Map에는 key에 대해서는 Set<K> keySet()이라는 key를 Set으로 가져오기를 지원하고, value에 대해서는 Collection<V> values() 를 제공합니다. 위에서 말씀드렸다시피 Set과 Collection은 둘다 Iterator를 제공합니다.
5. Enumeration vs Iterator
둘은 굉장히 유사합니다. Enumeration의 경우는 boolean hasMoreElements() 와 E nextElement() 를 제공합니다. Iterator의 hasNext() , next() 에 대응되는 메쏘드들이죠.
차이는 두 가집니다. 첫째 Iterator에는 remove()가 있다. 둘째, Iterator의 함수 이름이 훨씬 쉽다.(타이핑 노가다가 쭐어든다.-_-; )
처음에 Enumeration이 나왔고, 그걸 쫌 편하게 만들어보자한 것이 Iterator랍니다.
S-DES 소스 - java (0) | 2009.10.01 |
---|---|
POI - 시트복사 (0) | 2008.11.20 |
The Java XML Validation API - IBM developerworks (0) | 2008.09.19 |
Heap Dump 생성 (0) | 2008.09.18 |
VM 분석 : Chapter 1 Performance - 2 / -Xrunprof 옵션 (0) | 2008.09.17 |
08 Aug 2006
Validation reports whether a document adheres to the rules specified by the schema. Different parsers and tools support different schema languages such as DTDs, the W3C XML Schema Language, RELAX NG, and Schematron. Java 5™ adds a uniform validation Application Programming Interface (API) that can compare documents to schemas written in these and other languages. Learn about this XML validation API.
Validation is a powerful tool. It enables you to quickly check that input is roughly in the form you expect and quickly reject any document that is too far away from what your process can handle. If there's a problem with the data, it's better to find out earlier than later.
In the context of Extensible Markup Language (XML), validation normally involves writing a detailed specification for the document's contents in any of several schema languages such as the World Wide Web Consortium (W3C) XML Schema Language (XSD), RELAX NG, Document Type Definitions (DTDs), and Schematron. Sometimes validation is performed while parsing, sometimes immediately after. However, it's usually done before any further processing of the input takes place. (This description is painted with broad strokes -- there are exceptions.)
Until recently, the exact Application Programming Interface (API) by which programs requested validation varied with the schema language and parser. DTDs and XSD were normally accessed as configuration options in Simple API for XML (SAX), Document Object Model (DOM), and Java™ API for XML Processing (JAXP). RELAX NG required a custom library and API. Schematron might use the Transformations API for XML(TrAX); and still other schema languages required programmers to learn still more APIs, even though they were performing essentially the same operation.
Java 5 introduced the javax.xml.validation
package to provide a schema-language-independent interface to validation services. This package is also available in Java 1.3 and later when you install JAXP 1.3 separately. Among other products, an implementation of this library is included with Xerces 2.8.
The javax.xml.validation
API uses three classes to validate documents: SchemaFactory
, Schema
, and Validator
. It also makes extensive use of the javax.xml.transform.Source
interface from TrAX to represent the XML documents. In brief, a SchemaFactory
reads the schema document (often an XML file) from which it creates a Schema
object. The Schema
object creates a Validator
object. Finally, the Validator
object validates an XML document represented as a Source
.
Listing 1 shows a simple program to validate a URL entered on the command line against the DocBook XSD schema.
import java.io.*; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.*; import org.xml.sax.SAXException; public class DocbookXSDCheck { public static void main(String[] args) throws SAXException, IOException { // 1. Lookup a factory for the W3C XML Schema language SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); // 2. Compile the schema. // Here the schema is loaded from a java.io.File, but you could use // a java.net.URL or a javax.xml.transform.Source instead. File schemaLocation = new File("/opt/xml/docbook/xsd/docbook.xsd"); Schema schema = factory.newSchema(schemaLocation); // 3. Get a validator from the schema. Validator validator = schema.newValidator(); // 4. Parse the document you want to check. Source source = new StreamSource(args[0]); // 5. Check the document try { validator.validate(source); System.out.println(args[0] + " is valid."); } catch (SAXException ex) { System.out.println(args[0] + " is not valid because "); System.out.println(ex.getMessage()); } } } |
Here's some typical output when checking an invalid document using the version of Xerces bundled with Java 2 Software Development Kit (JDK) 5.0:
file:///Users/elharo/CS905/Course_Notes.xml is not valid because cvc-complex-type.2.3: Element 'legalnotice' cannot have character [children], because the type's content type is element-only.
You can easily change the schema to validate against, the document to validate, and even the schema language. However, in all cases, validation follows these five steps:
Source
object for the document you want to validate. A StreamSource
is usually simplest.
validate()
method throws a SAXException
. Otherwise, it returns quietly. You can reuse the same validator and the same schema multiple times in series. However, neither class is thread-safe or reentrant. If you validate in multiple threads simultaneously, make sure each one has its own Validator
and Schema
objects.
Validate against a document-specified schema
Some documents specify the schema they expect to be validated against, typically using xsi:noNamespaceSchemaLocation
and/or xsi:schemaLocation
attributes like this:
<document xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://www.example.com/document.xsd"> ... |
If you create a schema without specifying a URL, file, or source, then the Java language creates one that looks in the document being validated to find the schema it should use. For example:
SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); Schema schema = factory.newSchema(); |
However, normally this isn't what you want. Usually the document consumer should choose the schema, not the document producer. Furthermore, this approach works only for XSD. All other schema languages require an explicitly specified schema location.
|
SchemaFactory
is an abstract factory. The abstract factory design pattern enables this one API to support many different schema languages and object models. A single implementation usually supports only a subset of the numerous languages and models. However, once you learn the API for validating DOM documents against RELAX NG schemas (for instance), you can use the same API to validate JDOM documents against W3C schemas.
For example, Listing 2 shows a program that validates DocBook documents against DocBook's RELAX NG schema. It's almost identical to Listing 1. The only things that have changed are the location of the schema and the URL that identifies the schema language.
import java.io.*; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; import javax.xml.validation.*; import org.xml.sax.SAXException; public class DocbookRELAXNGCheck { public static void main(String[] args) throws SAXException, IOException { // 1. Specify you want a factory for RELAX NG SchemaFactory factory = SchemaFactory.newInstance("http://relaxng.org/ns/structure/1.0"); // 2. Load the specific schema you want. // Here I load it from a java.io.File, but we could also use a // java.net.URL or a javax.xml.transform.Source File schemaLocation = new File("/opt/xml/docbook/rng/docbook.rng"); // 3. Compile the schema. Schema schema = factory.newSchema(schemaLocation); // 4. Get a validator from the schema. Validator validator = schema.newValidator(); // 5. Parse the document you want to check. String input = "file:///Users/elharo/Projects/workspace/CS905/build/Java_Course_Notes.xml"; // 6. Check the document try { validator.validate(source); System.out.println(input + " is valid."); } catch (SAXException ex) { System.out.println(input + " is not valid because "); System.out.println(ex.getMessage()); } } } |
If you run this program with the stock Sun JDK and no extra libraries, you'll probably see something like this:
Exception in thread "main" java.lang.IllegalArgumentException: http://relaxng.org/ns/structure/1.0 at javax.xml.validation.SchemaFactory.newInstance(SchemaFactory.java:186) at DocbookRELAXNGCheck.main(DocbookRELAXNGCheck.java:14) |
This is because, out of the box, the JDK doesn't include a RELAX NG validator. When the schema language isn't recognized, SchemaFactory.newInstance()
throws an IllegalArgumentException
. However, if you install a RELAX NG library such as Jing and a JAXP 1.3 adapter, then it should produce the same answer the W3C schema does.
The javax.xml.constants
class defines several constants to identify schema languages:
XMLConstants.W3C_XML_SCHEMA_NS_URI
: http://www.w3.org/2001/XMLSchema
XMLConstants.RELAXNG_NS_URI
: http://relaxng.org/ns/structure/1.0
XMLConstants.XML_DTD_NS_URI
: http://www.w3.org/TR/REC-xml
This isn't a closed list. Implementations are free to add other URLs to this list to identify other schema languages. Typically, the URL is the namespace Uniform Resource Identifier (URI) for the schema language. For example, the URL http://www.ascc.net/xml/schematron
identifies Schematron schemas.
Sun's JDK 5 only supports XSD schemas. Although DTD validation is supported, it isn't accessible through the javax.xml.validation
API. For DTDs, you have to use the regular SAX XMLReader
class. However, you can install additional libraries that add support for these and other schema languages.
How schema factories are located
The Java programming language isn't limited to a single schema factory. When you pass a URI identifying a particular schema language to SchemaFactory.newInstance()
, it searches the following locations in this order to find a matching factory:
"javax.xml.validation.SchemaFactory:schemaURL"
system property
"javax.xml.validation.SchemaFactory:schemaURL"
property found in the $java.home/lib/jaxp.properties
file
javax.xml.validation.SchemaFactory
service providers found in the META-INF/services directories of any available Java Archive (JAR) files
SchemaFactory
, com.sun.org.apache.xerces.internal.jaxp.validation.xs.SchemaFactoryImpl
in JDK 5 To add support for your own custom schema language and corresponding validator, all you have to do is write subclasses of SchemaFactory
, Schema
, and Validator
that know how to process your schema language. Then, install your JAR in one of these four locations. This is useful for adding constraints that are more easily checked in a Turing-complete language like Java than in a declarative language like the W3C XML Schema language. You can define a mini-schema language, write a quick implementation, and plug it into the validation layer.
|
The default response from a schema is to throw a SAXException
if there's a problem and do nothing if there isn't. However, you can provide a SAX ErrorHandler
to receive more detailed information about the document's problems. For example, suppose you want to log all validation errors, but you don't want to stop processing when you encounter one. You can install an error handler such as that in Listing 3.
import org.xml.sax.ErrorHandler; import org.xml.sax.SAXException; import org.xml.sax.SAXParseException; public class ForgivingErrorHandler implements ErrorHandler { public void warning(SAXParseException ex) { System.err.println(ex.getMessage()); } public void error(SAXParseException ex) { System.err.println(ex.getMessage()); } public void fatalError(SAXParseException ex) throws SAXException { throw ex; } } |
To install this error handler, you create an instance of it and pass that instance to the Validator
's setErrorHandler()
method:
ErrorHandler lenient = new ForgivingErrorHandler(); validator.setErrorHandler(lenient); |
|
Some schemas do more than validate. As well as providing a true-false answer to the question of whether a document is valid, they also augment the document with additional information. For example, they can provide default attribute values. They might also assign types like int or gYear to an element or attribute. The validator can create such type-augmented documents and write them onto a javax.xml.transform.Result
object. All you need to do is pass a Result
as the second argument to validate. For example, Listing 4 both validates an input document and creates an augmented DOM document from the combination of the input with the schema.
import java.io.*; import javax.xml.transform.dom.*; import javax.xml.validation.*; import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.SAXException; public class DocbookXSDAugmenter { public static void main(String[] args) throws SAXException, IOException, ParserConfigurationException { SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); File schemaLocation = new File("/opt/xml/docbook/xsd/docbook.xsd"); Schema schema = factory.newSchema(schemaLocation); Validator validator = schema.newValidator(); DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); // never forget this DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse(new File(args[0])); DOMSource source = new DOMSource(doc); DOMResult result = new DOMResult(); try { validator.validate(source, result); Document augmented = (Document) result.getNode(); // do whatever you need to do with the augmented document... } catch (SAXException ex) { System.out.println(args[0] + " is not valid because "); System.out.println(ex.getMessage()); } } } |
This procedure can't transform an arbitrary source into an arbitrary result. It doesn't work at all for stream sources and results. SAX sources can be augmented into SAX results, and DOM sources into DOM results; but SAX sources can't be augmented to DOM results or vice versa. If you need to do that, first augment into the matching result -- SAX for SAX and DOM for DOM -- and then use TrAX's identity transform to change the model.
This technique isn't recommended, though. Putting all the information the document requires in the instance is far more reliable than splitting it between the instance and the schema. You might validate, but not everyone will.
|
The W3C XML Schema Language is heavily based on the notion of types. Elements and attributes are declared to be of type int, double, date, duration, person, PhoneNumber, or anything else you can imagine. The Java Validation API includes a means to report such types, although it's surprisingly independent of the rest of the package.
Types are identified by an org.w3c.dom.TypeInfo
object. This simple interface, summarized in Listing 5, tells you the local name and namespace URI of a type. You can also tell whether and how a type is derived from another type. Beyond that, understanding the type is up to your program. The Java language doesn't tell you what it means or convert the data to a Java type such as double
or java.util.Date
.
package org.w3c.dom; public interface TypeInfo { public static final int DERIVATION_RESTRICTION; public static final int DERIVATION_EXTENSION; public static final int DERIVATION_UNION; public String getTypeName(); public String getTypeNamespace() public boolean isDerivedFrom(String namespace, String name, int derivationMethod); } |
To get TypeInfo
objects, you ask the Schema
object for a ValidatorHandler
rather than a Validator
. ValidatorHandler
implements SAX's ContentHandler
interface. Then, you install this handler in a SAX parser.
You also install your own ContentHandler
in the ValidatorHandler
(not the parser); the ValidatorHandler
will forward the augmented events on to your ContentHandler
.
The ValidatorHandler
makes available a TypeInfoProvider
that your ContentHandler
can call at any time to find out the type of the current element or one of its attributes. It can also tell you whether an attribute is an ID, and whether the attribute was explicitly specified in the document or defaulted in from the schema. Listing 6 summarizes this class.
package javax.xml.validation; public abstract class TypeInfoProvider { public abstract TypeInfo getElementTypeInfo(); public abstract TypeInfo getAttributeTypeInfo(int index); public abstract boolean isIdAttribute(int index); public abstract boolean isSpecified(int index); } |
Finally, you parse the document with the SAX XMLReader
. Listing 7 shows a simple program that uses all these classes and interfaces to print out the names of all the types of the elements in a document.
import java.io.*; import javax.xml.validation.*; import org.xml.sax.*; import org.xml.sax.helpers.*; public class TypeLister extends DefaultHandler { private TypeInfoProvider provider; public TypeLister(TypeInfoProvider provider) { this.provider = provider; } public static void main(String[] args) throws SAXException, IOException { SchemaFactory factory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema"); File schemaLocation = new File("/opt/xml/docbook/xsd/docbook.xsd"); Schema schema = factory.newSchema(schemaLocation); ValidatorHandler vHandler = schema.newValidatorHandler(); TypeInfoProvider provider = vHandler.getTypeInfoProvider(); ContentHandler cHandler = new TypeLister(provider); vHandler.setContentHandler(cHandler); XMLReader parser = XMLReaderFactory.createXMLReader(); parser.setContentHandler(vHandler); parser.parse(args[0]); } public void startElement(String namespace, String localName, String qualifiedName, Attributes atts) throws SAXException { String type = provider.getElementTypeInfo().getTypeName(); System.out.println(qualifiedName + ": " + type); } } |
Here's the start of the output from running this code on a typical DocBook document:
book: #AnonType_book title: #AnonType_title subtitle: #AnonType_subtitle info: #AnonType_info copyright: #AnonType_copyright year: #AnonType_year holder: #AnonType_holder author: #AnonType_author personname: #AnonType_personname firstname: #AnonType_firstname othername: #AnonType_othername surname: #AnonType_surname personblurb: #AnonType_personblurb para: #AnonType_para link: #AnonType_link |
As you can see, the DocBook schema assigns most elements anonymous complex types. Obviously, this will vary from one schema to the next.
|
The world would be a poorer place if everyone spoke just one language. Programmers would be unhappy if they had only one programming language to choose from. Different languages suit different tasks better, and some tasks require more than one language. XML schemas are no different. You can choose from a plethora of useful schema languages. In Java 5 with javax.xml.validation
, you have an API that can handle all of them.
POI - 시트복사 (0) | 2008.11.20 |
---|---|
자바 디자인 패턴 1 - Iterator (0) | 2008.09.24 |
Heap Dump 생성 (0) | 2008.09.18 |
VM 분석 : Chapter 1 Performance - 2 / -Xrunprof 옵션 (0) | 2008.09.17 |
java.lang.OutOfMemoryError - OOME (0) | 2008.09.17 |