| 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', |