67 |
http://suika.fam.cx/~wakaba/archive/2004/dom/xml# |
http://suika.fam.cx/~wakaba/archive/2004/dom/xml# |
68 |
@xml: |
@xml: |
69 |
http://www.w3.org/XML/1998/namespace |
http://www.w3.org/XML/1998/namespace |
70 |
|
@xml-dtd: |
71 |
|
http://www.w3.org/TR/REC-xml |
72 |
@xmlns: |
@xmlns: |
73 |
http://www.w3.org/2000/xmlns/ |
http://www.w3.org/2000/xmlns/ |
74 |
@xp: |
@xp: |
280 |
$self->{standalone} = false; |
$self->{standalone} = false; |
281 |
$self->{general_entity} = {}; |
$self->{general_entity} = {}; |
282 |
$self->{param_entity} = {}; |
$self->{param_entity} = {}; |
283 |
|
$self->{attr} = {}; |
284 |
|
# $self->{attr}->{$element_type_name}->{$attr_name} = $attr_def |
285 |
$self->{has_error} = false; |
$self->{has_error} = false; |
286 |
## Well-formedness constraint Entity Declared takes effect? |
## Well-formedness constraint Entity Declared takes effect? |
287 |
|
|
986 |
} |
} |
987 |
|
|
988 |
my $el; |
my $el; |
989 |
|
|
990 |
|
/* |
991 |
|
Note that this implementation does not perform |
992 |
|
attribute value tokenization (but does white space |
993 |
|
normalization common to attribute types) and |
994 |
|
construct the tree as is. DOM Level 3 Core spec |
995 |
|
is unclear on this point. With tokenization, |
996 |
|
entity references cannot be preserved. |
997 |
|
|
998 |
|
The manakai Node.nodeValue and Attr.value attributes |
999 |
|
do tokenization according to attribute types. |
1000 |
|
*/ |
1001 |
|
|
1002 |
|
/* |
1003 |
|
ISSUE: Should |xml:id| attribute be typed? |
1004 |
|
*/ |
1005 |
|
|
1006 |
lang:Perl { |
lang:Perl { |
1007 |
push @{$nses}, $ns; |
push @{$nses}, $ns; |
1011 |
my %lattr; |
my %lattr; |
1012 |
for my $atqname (keys %$attrs) { |
for my $atqname (keys %$attrs) { |
1013 |
my ($pfx, $lname) = split /:/, $atqname; |
my ($pfx, $lname) = split /:/, $atqname; |
1014 |
|
$attrs->{$atqname}->{def} = $self->{attr}->{$type}->{$atqname}; |
1015 |
if (defined $lname) { ## Global attribute |
if (defined $lname) { ## Global attribute |
1016 |
## TODO: Namespace well-formedness (lname is NCName) |
## TODO: Namespace well-formedness (lname is NCName) |
1017 |
if ($pfx eq 'xmlns') { |
if ($pfx eq 'xmlns') { |
1031 |
## TODO: error |
## TODO: error |
1032 |
} |
} |
1033 |
$ns->{$lname} = $attrs->{$atqname}->{value}; |
$ns->{$lname} = $attrs->{$atqname}->{value}; |
1034 |
|
if ($attrs->{$atqname}->{def}) { |
1035 |
|
my $dt = $attrs->{$atqname}->{def}-><AG::ATDef.declaredType>; |
1036 |
|
if ({ |
1037 |
|
<C::ATDef.ID_ATTR> => true, |
1038 |
|
<C::ATDef.IDREF_ATTR> => true, |
1039 |
|
<C::ATDef.IDREFS_ATTR> => true, |
1040 |
|
<C::ATDef.ENTITY_ATTR> => true, |
1041 |
|
<C::ATDef.ENTITIES_ATTR> => true, |
1042 |
|
<C::ATDef.NMTOKEN_ATTR> => true, |
1043 |
|
<C::ATDef.NMTOKENS_ATTR> => true, |
1044 |
|
<C::ATDef.NOTATION_ATTR> => true, |
1045 |
|
<C::ATDef.ENUMERATION_ATTR> => true, |
1046 |
|
}->{$dt}) { |
1047 |
|
## Tokenization (XML 1 3.3.3) |
1048 |
|
for ($ns->{$lname}) { |
1049 |
|
s/^\x20+//; |
1050 |
|
s/\x20+\z//; |
1051 |
|
s/\x20+/ /g; |
1052 |
|
} |
1053 |
|
} |
1054 |
|
} |
1055 |
delete $ns->{$lname} unless length $ns->{$lname}; |
delete $ns->{$lname} unless length $ns->{$lname}; |
1056 |
} elsif ($pfx eq '') { |
} elsif ($pfx eq '') { |
1057 |
## TODO: pfx is not NCName error |
## TODO: pfx is not NCName error |
1064 |
} else { ## Local attribute |
} else { ## Local attribute |
1065 |
if ($pfx eq 'xmlns') { |
if ($pfx eq 'xmlns') { |
1066 |
$ns->{''} = $attrs->{xmlns}->{value}; |
$ns->{''} = $attrs->{xmlns}->{value}; |
1067 |
|
if ($attrs->{$atqname}->{def}) { |
1068 |
|
my $dt = $attrs->{$atqname}->{def}-><AG::ATDef.declaredType>; |
1069 |
|
if ({ |
1070 |
|
<C::ATDef.ID_ATTR> => true, |
1071 |
|
<C::ATDef.IDREF_ATTR> => true, |
1072 |
|
<C::ATDef.IDREFS_ATTR> => true, |
1073 |
|
<C::ATDef.ENTITY_ATTR> => true, |
1074 |
|
<C::ATDef.ENTITIES_ATTR> => true, |
1075 |
|
<C::ATDef.NMTOKEN_ATTR> => true, |
1076 |
|
<C::ATDef.NMTOKENS_ATTR> => true, |
1077 |
|
<C::ATDef.NOTATION_ATTR> => true, |
1078 |
|
<C::ATDef.ENUMERATION_ATTR> => true, |
1079 |
|
}->{$dt}) { |
1080 |
|
## Tokenization (XML 1 3.3.3) |
1081 |
|
for ($ns->{''}) { |
1082 |
|
s/^\x20+//; |
1083 |
|
s/\x20+\z//; |
1084 |
|
s/\x20+/ /g; |
1085 |
|
} |
1086 |
|
} |
1087 |
|
} |
1088 |
delete $ns->{''} unless length $ns->{''}; |
delete $ns->{''} unless length $ns->{''}; |
1089 |
} else { |
} else { |
1090 |
$lattr{$pfx} = $attrs->{$atqname}; |
$lattr{$pfx} = $attrs->{$atqname}; |
1117 |
for (@{$attrs->{xmlns}->{nodes}}) { |
for (@{$attrs->{xmlns}->{nodes}}) { |
1118 |
$attr-><M::Node.appendChild> ($_); |
$attr-><M::Node.appendChild> ($_); |
1119 |
} |
} |
1120 |
|
if ($attrs->{xmlns}->{def}) { |
1121 |
|
__CODE{t|setAttrType:: |
1122 |
|
$attr => $attr, |
1123 |
|
$type => {$attrs->{xmlns}->{def}-><AG::ATDef.declaredType>}, |
1124 |
|
}__; |
1125 |
|
} |
1126 |
$el-><M::Element.setAttributeNodeNS> ($attr); |
$el-><M::Element.setAttributeNodeNS> ($attr); |
1127 |
} |
} |
1128 |
|
|
1132 |
for (@{$lattr{$lname}->{nodes}}) { |
for (@{$lattr{$lname}->{nodes}}) { |
1133 |
$attr-><M::Node.appendChild> ($_); |
$attr-><M::Node.appendChild> ($_); |
1134 |
} |
} |
1135 |
|
if ($attrs->{$lname}->{def}) { |
1136 |
|
__CODE{t|setAttrType:: |
1137 |
|
$attr => $attr, |
1138 |
|
$type => {$attrs->{$lname}->{def}-><AG::ATDef.declaredType>}, |
1139 |
|
}__; |
1140 |
|
} |
1141 |
$el-><M::Element.setAttributeNodeNS> ($attr); |
$el-><M::Element.setAttributeNodeNS> ($attr); |
1142 |
} |
} |
1143 |
|
|
1148 |
for (@{$gattr{$pfx}->{$lname}->{nodes}}) { |
for (@{$gattr{$pfx}->{$lname}->{nodes}}) { |
1149 |
$attr-><M::Node.appendChild> ($_); |
$attr-><M::Node.appendChild> ($_); |
1150 |
} |
} |
1151 |
|
if ($attrs->{$pfx}->{$lname}->{def}) { |
1152 |
|
__CODE{t|setAttrType:: |
1153 |
|
$attr => $attr, |
1154 |
|
$type => {$attrs->{$pfx}->{$lname} |
1155 |
|
->{def}-><AG::ATDef.declaredType>}, |
1156 |
|
}__; |
1157 |
|
} |
1158 |
$el-><M::Element.setAttributeNodeNS> ($attr); |
$el-><M::Element.setAttributeNodeNS> ($attr); |
1159 |
} |
} |
1160 |
} |
} |
1570 |
$self->{has_error} = true; |
$self->{has_error} = true; |
1571 |
} |
} |
1572 |
my $ncr = $doc-><M::Document.createTextNode> |
my $ncr = $doc-><M::Document.createTextNode> |
1573 |
(my $char = chr (0+$num)); |
(my $char = chr $num); |
1574 |
push @{$vals->{nodes}}, $ncr; |
push @{$vals->{nodes}}, $ncr; |
1575 |
$vals->{value} .= $char; |
$vals->{value} .= $char; |
1576 |
} |
} |
1583 |
?lexmode 'HexadecimalCharacterReference'; |
?lexmode 'HexadecimalCharacterReference'; |
1584 |
|
|
1585 |
~ (Hex) { |
~ (Hex) { |
1586 |
lang:Perl ($num => $token.value) : has-error { |
lang:Perl ($v => $token.value) : has-error { |
1587 |
$num += 0; |
my $num = hex $v; |
1588 |
unless ( |
unless ( |
1589 |
($self->{xml_version} eq '1.0' and |
($self->{xml_version} eq '1.0' and |
1590 |
((0x0020 <= $num and $num <= 0xD7FF) or |
((0x0020 <= $num and $num <= 0xD7FF) or |
1613 |
$self->{has_error} = true; |
$self->{has_error} = true; |
1614 |
} |
} |
1615 |
my $ncr = $doc-><M::Document.createTextNode> |
my $ncr = $doc-><M::Document.createTextNode> |
1616 |
(chr hex $num); |
(chr $num); |
1617 |
$parent-><M::Node.appendChild> ($ncr); |
$parent-><M::Node.appendChild> ($ncr); |
1618 |
} |
} |
1619 |
} |
} |
1625 |
?lexmode 'HexadecimalCharacterReference'; |
?lexmode 'HexadecimalCharacterReference'; |
1626 |
|
|
1627 |
~ (Hex) { |
~ (Hex) { |
1628 |
lang:Perl ($num => $token.value) : has-error { |
lang:Perl ($v => $token.value) : has-error { |
1629 |
$num += 0; |
my $num = hex $v; |
1630 |
unless ( |
unless ( |
1631 |
($self->{xml_version} eq '1.0' and |
($self->{xml_version} eq '1.0' and |
1632 |
((0x0020 <= $num and $num <= 0xD7FF) or |
((0x0020 <= $num and $num <= 0xD7FF) or |
1654 |
$self->{has_error} = true; |
$self->{has_error} = true; |
1655 |
} |
} |
1656 |
my $ncr = $doc-><M::Document.createTextNode> |
my $ncr = $doc-><M::Document.createTextNode> |
1657 |
(my $char = chr hex $num); |
(my $char = chr $num); |
1658 |
push @{$vals->{nodes}}, $ncr; |
push @{$vals->{nodes}}, $ncr; |
1659 |
$vals->{value} .= $char; |
$vals->{value} .= $char; |
1660 |
} |
} |
1822 |
lang:Perl { |
lang:Perl { |
1823 |
$node = $doc-><M::DocumentXDoctype.createDocumentTypeDefinition> ($name); |
$node = $doc-><M::DocumentXDoctype.createDocumentTypeDefinition> ($name); |
1824 |
$doc-><M::Node.appendChild> ($node); |
$doc-><M::Node.appendChild> ($node); |
1825 |
|
$doc-><AG::Document.domConfig> |
1826 |
|
-><M::c|DOMConfiguration.setParameter> |
1827 |
|
('schema-type' => <Q::xml-dtd:>); |
1828 |
} |
} |
1829 |
|
|
1830 |
~? (S) { |
~? (S) { |
2154 |
$docxd ||= $doc-><M::Node.getFeature> |
$docxd ||= $doc-><M::Node.getFeature> |
2155 |
(<Q::ManakaiDOM:XDoctype>, '3.0'); |
(<Q::ManakaiDOM:XDoctype>, '3.0'); |
2156 |
$at = $docxd-><M::DocumentXDoctype.createAttributeDefinition> ($v); |
$at = $docxd-><M::DocumentXDoctype.createAttributeDefinition> ($v); |
2157 |
$et-><M::ETDef.setAttributeDefinitionNode> ($at) |
unless (exists $et-><AG::ETDef.attributeDefinitions>->{$v}) { |
2158 |
unless exists $et-><AG::ETDef.attributeDefinitions>->{$v}; |
$et-><M::ETDef.setAttributeDefinitionNode> ($at); |
2159 |
|
$self->{attr}->{$name}->{$v} = $at; |
2160 |
|
} |
2161 |
} |
} |
2162 |
|
|
2163 |
~ (S) { } |
~ (S) { } |
3921 |
} |
} |
3922 |
} |
} |
3923 |
|
|
3924 |
|
@@XMLTest: |
3925 |
|
@@@QName: xp.doctype.internal.attr.cdata.default.normalize.test |
3926 |
|
@@@DEnt: |
3927 |
|
@@@@test:value: |
3928 |
|
<!DOCTYPE a [ |
3929 |
|
<!ATTLIST a |
3930 |
|
at CDATA " default 
value " |
3931 |
|
> |
3932 |
|
]> |
3933 |
|
<a></a> |
3934 |
|
@@@test:domTree: |
3935 |
|
document { |
3936 |
|
xml-version: '1.0'; |
3937 |
|
xml-encoding: null; |
3938 |
|
xml-standalone: false; |
3939 |
|
document-type { |
3940 |
|
node-name: 'a'; |
3941 |
|
element-type-definition { |
3942 |
|
node-name: 'a'; |
3943 |
|
attribute-definition { |
3944 |
|
node-name: 'at'; |
3945 |
|
declared-type: const (CDATA_ATTR); |
3946 |
|
allowed-tokens: DOMStringList (); |
3947 |
|
default-type: const (EXPLICIT_DEFAULT); |
3948 |
|
text-content: ' default ' U+000A 'value '; |
3949 |
|
} |
3950 |
|
} |
3951 |
|
} |
3952 |
|
element { |
3953 |
|
namespace-uri: null; |
3954 |
|
local-name: 'a'; |
3955 |
|
} |
3956 |
|
} |
3957 |
|
@@XMLTest: |
3958 |
|
@@@QName: xp.doctype.internal.attr.nmtoken.default.normalize.test |
3959 |
|
@@@DEnt: |
3960 |
|
@@@@test:value: |
3961 |
|
<!DOCTYPE a [ |
3962 |
|
<!ATTLIST a |
3963 |
|
at NMTOKEN " default 
value " |
3964 |
|
> |
3965 |
|
]> |
3966 |
|
<a></a> |
3967 |
|
@@@test:domTree: |
3968 |
|
document { |
3969 |
|
xml-version: '1.0'; |
3970 |
|
xml-encoding: null; |
3971 |
|
xml-standalone: false; |
3972 |
|
document-type { |
3973 |
|
node-name: 'a'; |
3974 |
|
element-type-definition { |
3975 |
|
node-name: 'a'; |
3976 |
|
attribute-definition { |
3977 |
|
node-name: 'at'; |
3978 |
|
declared-type: const (NMTOKEN_ATTR); |
3979 |
|
allowed-tokens: DOMStringList (); |
3980 |
|
default-type: const (EXPLICIT_DEFAULT); |
3981 |
|
text-content: ' default ' U+000A 'value '; |
3982 |
|
} |
3983 |
|
} |
3984 |
|
} |
3985 |
|
element { |
3986 |
|
namespace-uri: null; |
3987 |
|
local-name: 'a'; |
3988 |
|
} |
3989 |
|
} |
3990 |
|
|
3991 |
|
@@XMLTest: |
3992 |
|
@@@QName: xp.doctype.attrtype.no-value.test |
3993 |
|
@@@DEnt: |
3994 |
|
@@@@test:value: |
3995 |
|
<!DOCTYPE a> |
3996 |
|
<a at=" at value "></a> |
3997 |
|
@@@test:domTree: |
3998 |
|
document { |
3999 |
|
xml-version: '1.0'; |
4000 |
|
xml-encoding: null; |
4001 |
|
xml-standalone: false; |
4002 |
|
document-type { } |
4003 |
|
element { |
4004 |
|
namespace-uri: null; |
4005 |
|
local-name: 'a'; |
4006 |
|
attribute { |
4007 |
|
namespace-uri: null; |
4008 |
|
local-name: 'at'; |
4009 |
|
value: ' at value '; |
4010 |
|
text { |
4011 |
|
data: ' at value '; |
4012 |
|
} |
4013 |
|
schema-type-info: TypeInfo (null, null); |
4014 |
|
} |
4015 |
|
} |
4016 |
|
} |
4017 |
|
@@XMLTest: |
4018 |
|
@@@QName: xp.doctype.attrtype.cdata.test |
4019 |
|
@@@DEnt: |
4020 |
|
@@@@test:value: |
4021 |
|
<!DOCTYPE a [ |
4022 |
|
<!ATTLIST a |
4023 |
|
at CDATA #IMPLIED |
4024 |
|
> |
4025 |
|
]> |
4026 |
|
<a at=" at value "></a> |
4027 |
|
@@@test:domTree: |
4028 |
|
document { |
4029 |
|
xml-version: '1.0'; |
4030 |
|
xml-encoding: null; |
4031 |
|
xml-standalone: false; |
4032 |
|
document-type { } |
4033 |
|
element { |
4034 |
|
namespace-uri: null; |
4035 |
|
local-name: 'a'; |
4036 |
|
attribute { |
4037 |
|
namespace-uri: null; |
4038 |
|
local-name: 'at'; |
4039 |
|
value: ' at value '; |
4040 |
|
text { |
4041 |
|
data: ' at value '; |
4042 |
|
} |
4043 |
|
schema-type-info: |
4044 |
|
TypeInfo ('http://www.w3.org/TR/REC-xml', 'CDATA'); |
4045 |
|
} |
4046 |
|
} |
4047 |
|
} |
4048 |
|
@@XMLTest: |
4049 |
|
@@@QName: xp.doctype.attrtype.nmtoken.test |
4050 |
|
@@@DEnt: |
4051 |
|
@@@@test:value: |
4052 |
|
<!DOCTYPE a [ |
4053 |
|
<!ATTLIST a |
4054 |
|
at NMTOKEN #IMPLIED |
4055 |
|
> |
4056 |
|
]> |
4057 |
|
<a at=" at value "></a> |
4058 |
|
@@@test:domTree: |
4059 |
|
document { |
4060 |
|
xml-version: '1.0'; |
4061 |
|
xml-encoding: null; |
4062 |
|
xml-standalone: false; |
4063 |
|
document-type { } |
4064 |
|
element { |
4065 |
|
namespace-uri: null; |
4066 |
|
local-name: 'a'; |
4067 |
|
attribute { |
4068 |
|
namespace-uri: null; |
4069 |
|
local-name: 'at'; |
4070 |
|
value: 'at value'; |
4071 |
|
text { |
4072 |
|
data: ' at value '; |
4073 |
|
} |
4074 |
|
schema-type-info: |
4075 |
|
TypeInfo ('http://www.w3.org/TR/REC-xml', 'NMTOKEN'); |
4076 |
|
} |
4077 |
|
} |
4078 |
|
} |
4079 |
|
|
4080 |
|
@@XMLTest: |
4081 |
|
@@@QName: xp.doctype.attr.normalization.1.test |
4082 |
|
@@@DEnt: |
4083 |
|
@@@@test:value: |
4084 |
|
<a at=" at 
value "></a> |
4085 |
|
@@@test:domTree: |
4086 |
|
document { |
4087 |
|
element { |
4088 |
|
attribute { |
4089 |
|
value: ' at ' U+000A 'value '; |
4090 |
|
schema-type-info: TypeInfo (null, null); |
4091 |
|
} |
4092 |
|
} |
4093 |
|
} |
4094 |
|
@@XMLTest: |
4095 |
|
@@@QName: xp.doctype.attr.normalization.2.test |
4096 |
|
@@@DEnt: |
4097 |
|
@@@@test:value: |
4098 |
|
<a at=" at 
value "></a> |
4099 |
|
@@@test:domTree: |
4100 |
|
document { |
4101 |
|
element { |
4102 |
|
attribute { |
4103 |
|
value: ' at ' U+000D 'value '; |
4104 |
|
schema-type-info: TypeInfo (null, null); |
4105 |
|
} |
4106 |
|
} |
4107 |
|
} |
4108 |
|
@@XMLTest: |
4109 |
|
@@@QName: xp.doctype.attr.normalization.3.test |
4110 |
|
@@@DEnt: |
4111 |
|
@@@@test:value: |
4112 |
|
<a at=" at 	value "></a> |
4113 |
|
@@@test:domTree: |
4114 |
|
document { |
4115 |
|
element { |
4116 |
|
attribute { |
4117 |
|
value: ' at ' U+0009 'value '; |
4118 |
|
schema-type-info: TypeInfo (null, null); |
4119 |
|
} |
4120 |
|
} |
4121 |
|
} |
4122 |
|
|
4123 |
@@PerlDef: |
@@PerlDef: |
4124 |
my $impl = $Message::DOM::ImplementationRegistry->get_implementation ({ |
my $impl = $Message::DOM::ImplementationRegistry->get_implementation ({ |
4125 |
'Core' => '3.0', |
'Core' => '3.0', |