Przeglądaj źródła

* fcl-xml, upgrade to comply with XML 1.0 Fifth Edition. This makes naming rules for xml 1.0 identical to ones for xml 1.1.

git-svn-id: trunk@20422 -
sergei 13 lat temu
rodzic
commit
6adf381867

+ 12 - 12
packages/fcl-xml/src/dom.pp

@@ -2019,11 +2019,11 @@ end;
 { if nsIdx = -1, checks only the name. Otherwise additionally checks if the prefix is
   valid for standard namespace specified by nsIdx. 
   Non-negative return value is Pos(':', QName), negative is DOM error code. }
-function CheckQName(const QName: DOMString; nsIdx: Integer; Xml11: Boolean): Integer;
+function CheckQName(const QName: DOMString; nsIdx: Integer): Integer;
 var
   I, L: Integer;
 begin
-  if not IsXmlName(QName, Xml11) then
+  if not IsXmlName(QName) then
   begin
     Result := -INVALID_CHARACTER_ERR;
     Exit;
@@ -2041,7 +2041,7 @@ begin
       end;
     // Name validity has already been checked by IsXmlName() call above.  
     // So just check that colon isn't first or last char, and that it is follwed by NameStartChar.
-    if ((Result = 1) or (Result = L) or not IsXmlName(@QName[Result+1], 1, Xml11)) then
+    if ((Result = 1) or (Result = L) or not IsXmlName(@QName[Result+1], 1)) then
     begin
       Result := -NAMESPACE_ERR;
       Exit;
@@ -2074,7 +2074,7 @@ var
   res: Integer;
   model: TDTDModel;
 begin
-  res := CheckQName(QualifiedName, -1, False);
+  res := CheckQName(QualifiedName, -1);
   if res < 0 then
     raise EDOMError.Create(-res, 'Implementation.CreateDocumentType');
   model := TDTDModel.Create(nil); // !!nowhere to get nametable from at this time
@@ -2280,7 +2280,7 @@ end;
 
 function TDOMDocument.CreateElement(const tagName: DOMString): TDOMElement;
 begin
-  if not IsXmlName(tagName, FXMLVersion = xmlVersion11) then
+  if not IsXmlName(tagName) then
     raise EDOMError.Create(INVALID_CHARACTER_ERR, 'DOMDocument.CreateElement');
   TDOMNode(Result) := Alloc(TDOMElement);
   Result.Create(Self);
@@ -2348,7 +2348,7 @@ end;
 
 function TDOMDocument.CreateAttribute(const name: DOMString): TDOMAttr;
 begin
-  if not IsXmlName(name, FXMLVersion = xmlVersion11) then
+  if not IsXmlName(name) then
     raise EDOMError.Create(INVALID_CHARACTER_ERR, 'DOMDocument.CreateAttribute');
   TDOMNode(Result) := Alloc(TDOMAttr);
   Result.Create(Self);
@@ -2450,7 +2450,7 @@ var
   idx, PrefIdx: Integer;
 begin
   idx := IndexOfNS(nsURI, True);
-  PrefIdx := CheckQName(QualifiedName, idx, FXMLVersion = xmlVersion11);
+  PrefIdx := CheckQName(QualifiedName, idx);
   if PrefIdx < 0 then
     raise EDOMError.Create(-PrefIdx, 'Document.CreateAttributeNS');
   TDOMNode(Result) := Alloc(TDOMAttr);
@@ -2468,7 +2468,7 @@ var
   idx, PrefIdx: Integer;
 begin
   idx := IndexOfNS(nsURI, True);
-  PrefIdx := CheckQName(QualifiedName, idx, FXMLVersion = xmlVersion11);
+  PrefIdx := CheckQName(QualifiedName, idx);
   if PrefIdx < 0 then
     raise EDOMError.Create(-PrefIdx, 'Document.CreateElementNS');
   TDOMNode(Result) := Alloc(TDOMElement);
@@ -2541,7 +2541,7 @@ end;
 function TXMLDocument.CreateProcessingInstruction(const target,
   data: DOMString): TDOMProcessingInstruction;
 begin
-  if not IsXmlName(target, FXMLVersion = xmlVersion11) then
+  if not IsXmlName(target) then
     raise EDOMError.Create(INVALID_CHARACTER_ERR, 'XMLDocument.CreateProcessingInstruction');
   TDOMNode(Result) := Alloc(TDOMProcessingInstruction);
   Result.Create(Self);
@@ -2555,7 +2555,7 @@ var
   dType: TDOMDocumentType;
   ent: TDOMEntity;
 begin
-  if not IsXmlName(name, FXMLVersion = xmlVersion11) then
+  if not IsXmlName(name) then
     raise EDOMError.Create(INVALID_CHARACTER_ERR, 'XMLDocument.CreateEntityReference');
   TDOMNode(Result) := Alloc(TDOMEntityReference);
   Result.Create(Self);
@@ -2624,7 +2624,7 @@ var
   NewName: DOMString;
 begin
   Changing;
-  if not IsXmlName(Value, FOwnerDocument.FXMLVersion = xmlVersion11) then
+  if not IsXmlName(Value) then
     raise EDOMError.Create(INVALID_CHARACTER_ERR, 'Node.SetPrefix');
 
   if (Pos(WideChar(':'), Value) > 0) or not (nfLevel2 in FFlags) or
@@ -2979,7 +2979,7 @@ var
 begin
   Changing;
   idx := FOwnerDocument.IndexOfNS(nsURI, True);
-  prefIdx := CheckQName(qualifiedName, idx, FOwnerDocument.FXMLVersion = xmlVersion11);
+  prefIdx := CheckQName(qualifiedName, idx);
   if prefIdx < 0 then
     raise EDOMError.Create(-prefIdx, 'Element.SetAttributeNS');
 

+ 41 - 174
packages/fcl-xml/src/names.inc

@@ -18,171 +18,42 @@ type
 const
 // colon ($3a) is excluded, it is handled in the code
   ns_ASCII = [{ $3A,} $41..$5A, $5F, $61..$7A, $C0..$D6, $D8..$F6, $F8..$FF];
-  ns_0200  = [0..$17, $50..$A8, $BB..$C1];
-  ns_0300  = [$86, $88..$8A, $8C, $8E..$A1,
-              $A3..$CE, $D0..$D6, $DA, $DC,
-              $DE, $E0, $E2..$F3];
-  ns_0400  = [$01..$0C, $0E..$4F, $51..$5C,
-              $5E..$81, $90..$C4, $C7..$C8,
-              $CB..$CC, $D0..$EB, $EE..$F5,
-              $F8..$F9];
-  ns_0500  = [$31..$56, $59, $61..$86, $D0..$EA, $F0..$F2];
-  ns_0600  = [$21..$3A, $41..$4A, $71..$B7,
-              $BA..$BE, $C0..$CE, $D0..$D3,
-              $D5, $E5..$E6];
-  ns_0900  = [$05..$39, $3D, $58..$61,
-              $85..$8C, $8F..$90, $93..$A8,
-              $AA..$B0, $B2, $B6..$B9,
-              $DC..$DD, $DF..$E1, $F0..$F1];
-  ns_0A00  = [$05..$0A, $0F..$10, $13..$28,
-              $2A..$30, $32..$33, $35..$36,
-              $38..$39, $59..$5C, $5E, $72..$74,
-              $85..$8B, $8D, $8F..$91, $93..$A8,
-              $AA..$B0, $B2..$B3, $B5..$B9, $BD, $E0];
-  ns_0B00  = [$05..$0C, $0F..$10, $13..$28,
-              $2A..$30, $32..$33, $36..$39,
-              $3D, $5C..$5D, $5F..$61, $85..$8A,
-              $8E..$90, $92..$95, $99..$9A,
-              $9C, $9E..$9F, $A3..$A4, $A8..$AA,
-              $AE..$B5, $B7..$B9];
-  ns_0C00  = [$05..$0C, $0E..$10, $12..$28,
-              $2A..$33, $35..$39, $60..$61,
-              $85..$8C, $8E..$90, $92..$A8,
-              $AA..$B3, $B5..$B9, $DE, $E0..$E1];
-  ns_0D00  = [$05..$0C, $0E..$10, $12..$28, $2A..$39, $60..$61];
-  ns_0E00  = [$01..$2E, $30, $32..$33, $40..$45,
-              $81..$82, $84, $87..$88, $8A, $8D,
-              $94..$97, $99..$9F, $A1..$A3,
-              $A5, $A7, $AA..$AB, $AD..$AE,
-              $B0, $B2..$B3, $BD, $C0..$C4];
-  ns_0F00  = [$40..$47, $49..$69];
 
-  ns_3000  = [$41..$94, $A1..$FA] + [$07, $21..$29];
-
-  namingBitmap: array[0..$30] of TSetOfByte = (
+  namingBitmap: array[0..$0C] of TSetOfByte = (
 
   [],                              // 00 - nothing allowed
   [0..255],                        // 01 - all allowed
   ns_ASCII,                        // 02
-  [0..$31, $34..$3E, $41..$48,     // 03 - $0100, both Name and NameStart
-   $4A..$7E, $80..$C3, $CD..$F0,
-   $F4..$F5, $FA..$FF],
-
-  ns_0200,                  // 04
-  ns_0300,                  // 05
-  ns_0400,                  // 06
-  ns_0500,                  // 07
-  ns_0600,                  // 08
-  ns_0900,                  // 09
-  ns_0A00,                  // 0A
-  ns_0B00,                  // 0B
-  ns_0C00,                  // 0C
-  ns_0D00,                  // 0D
-  ns_0E00,                  // 0E
-  ns_0F00,                  // 0F
-  [$A0..$C5, $D0..$F6],            // 10 - $1000, both Name and NameStart
-  [0, $02..03, $05..$07, $09,      // 11 - $1100, both Name and NameStart
-   $0B..$0C, $0E..$12, $3C, $3E,
-   $40, $4C, $4E, $50, $54..$55,
-   $59, $5F..$61, $63, $65, $67,
-   $69, $6D..$6E, $72..$73, $75,
-   $9E, $A8, $AB, $AE..$AF,
-   $B7..$B8, $BA, $BC..$C2, $EB, $F0, $F9],
-  [0..$9B, $A0..$F9],              // 12 - $1E00, both Name and NameStart
-  [0..$15, $18..$1D, $20..$45,     // 13 - $1F00, both Name and NameStart
-   $48..$4D, $50..$57, $59, $5B, $5D,
-   $5F..$7D, $80..$B4, $B6..$BC, $BE,
-   $C2..$C4, $C6..$CC, $D0..$D3,
-   $D6..$DB, $E0..$EC, $F2..$F4, $F6..$FC],
-  [$26, $2A..$2B, $2E, $80..$82],  // 14 - $2100, NameStart
-  ns_3000,                         // 15
-  [$05..$2C],                      // 16 - $3100, NameStart
-  [0..$A5],                        // 17 - $9F00, NameStart (ideographs)
-  [0..$A3],                        // 18 - $D700, NameStart
 
-  ns_ASCII +                       // 19 - $0000, Names
+  ns_ASCII +                       // 03 - $0000, Names
     [$2D..$2E, $30..$39, $B7],
-  ns_0200 +                        // 1A - $0200, Names
-    [$D0..$D1],
-  ns_0300 +                        // 1B - $0300, Names
-    [0..$45, $60..$61, $87],
-  ns_0400 +                        // 1C - $0400, Names
-    [$83..$86],
-  ns_0500 +                        // 1D - $0500, Names
-    [$91..$A1, $A3..$B9, $BB..$BD,         { combining }
-    $BF, $C1..$C2, $C4],
-  ns_0600 +                        // 1E - $0600, Names
-    [$4B..$52, $70, $D6..$DC, $DD..$DF,    { combining }
-     $E0..$E4, $E7..$E8, $EA..$ED] +
-    [$60..$69, $F0..$F9] + [$40],          { digits + ext }
-  ns_0900 +                        // 1F - $0900, Names
-    [$01..$03, $3C, $3E..$4C, $4D,         { combining }
-     $51..$54, $62..$63, $81..$83,
-     $BC, $BE, $BF, $C0..$C4, $C7..$C8,
-     $CB..$CD, $D7, $E2..$E3] +
-     [$66..$6F, $E6..$EF],                 { digits }
-  ns_0A00 +                        // 20 - $0A00, Names
-  [$02, $3C, $3E..$42, $47..$48, $4B..$4D, { combining }
-   $70..$71, $81..$83, $BC, $BE..$C5,
-   $C7..$C9, $CB..$CD] +
-  [$66..$6F, $E6..$EF],                    { digits }
-  ns_0B00 +                        // 21 - $0B00, Names
-  [$01..$03, $3C, $3E..$43, $47..$48,      { combining }
-   $4B..$4D, $56..$57, $82..$83, $BE..$C2,
-   $C6..$C8, $CA..$CD, $D7] +
-  [$66..$6F, $E7..$EF],                    { digits }
-  ns_0C00 +                        // 22 - $0C00, Names
-    [$01..$03, $3E..$44, $46..$48,        { combining }
-     $4A..$4D, $55..$56, $82..$83,
-     $BE..$C4, $C6..$C8, $CA..$CD, $D5..$D6] +
-    [$66..$6F, $E6..$EF],                { digits }
-  ns_0D00 +                        // 23 - $0D00, Names
-    [$02..$03, $3E..$43,                { combining }
-     $46..$48, $4A..$4D, $57] +
-    [$66..$6F],                         { digits }
-  ns_0E00 +                        // 24 - $0E00, Names
-    [$31, $34..$3A, $47..$4E,           { combining }
-     $B1, $B4..$B9, $BB..$BC,
-     $C8..$CD] +
-    [$50..$59, $D0..$D9] +              { digits }
-    [$46, $C6],                         { extenders }
-  ns_0F00 +                        // 25 - $0F00, Names
-    [$18..$19, $35, $37, $39,           { combining }
-     $3E, $3F, $71..$84, $86..$8B,
-     $90..$95, $97, $99..$AD,
-     $B1..$B7, $B9] +
-    [$20..$29],                         { digits }
-    [$D0..$DC, $E1],               // 26 - $2000, Names (combining)
-  ns_3000 +                        // 27 - $3000, Names
-    [$2A..$2F, $99, $9A] +               { combining }
-    [$05, $31..$35, $9D..$9E, $FC..$FE], { extenders }
-
-{ XML 1.1 additions }
 
-  [0..$CF, $F0..$FF],              // 28 $FD00 - NameStart
-  [0..$EF],                        // 29 $2F00 - NameStart
-  [$0C..$0D, $70..$FF],            // 2A $2000 - NameStart
-  [0..$8F],                        // 2B $2100 - NameStart
-  [$70..$7D, $7F..$FF],            // 2C $0300 - NameStart
-  [1..$FF],                        // 2D $3000 - NameStart
-  [0..$7D, $7F..$FF],              // 2E $0300 - Names
-  [$0C..$0D, $3F..$40, $70..$FF],  // 2F $2000 - Names
-  [$00..$FD]                       // 30 $FF00 - both Name and NameStart
+  [0..$CF, $F0..$FF],              // 04 $FD00 - NameStart
+  [0..$EF],                        // 05 $2F00 - NameStart
+  [$0C..$0D, $70..$FF],            // 06 $2000 - NameStart
+  [0..$8F],                        // 07 $2100 - NameStart
+  [$70..$7D, $7F..$FF],            // 08 $0300 - NameStart
+  [1..$FF],                        // 09 $3000 - NameStart
+  [0..$7D, $7F..$FF],              // 0A $0300 - Names
+  [$0C..$0D, $3F..$40, $70..$FF],  // 0B $2000 - Names
+  [$00..$FD]                       // 0C $FF00 - both Name and NameStart
 );
 
-  Xml11HighPages: TSetOfByte = [0..$21, $2C..$D7, $F9..$FE];
-
   NamePages: array[0..511] of Byte = (
-$02, $03, $04, $05, $06, $07, $08, $00,
-$00, $09, $0A, $0B, $0C, $0D, $0E, $0F,
-$10, $11, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $00, $00, $12, $13,
-$00, $14, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $00, $00, $00, $00,
-$15, $16, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $00, $00, $01, $01,
+$02, $01, $01, $08, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$06, $07, $00, $00, $00, $00, $00, $00,
+$00, $00, $00, $00, $01, $01, $01, $05,
+$09, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
@@ -192,30 +63,30 @@ $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
-$01, $01, $01, $01, $01, $01, $01, $17,
-$00, $00, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
-$01, $01, $01, $01, $01, $01, $01, $18,
-$00, $00, $00, $00, $00, $00, $00, $00,
 $00, $00, $00, $00, $00, $00, $00, $00,
 $00, $00, $00, $00, $00, $00, $00, $00,
 $00, $00, $00, $00, $00, $00, $00, $00,
 $00, $00, $00, $00, $00, $00, $00, $00,
+$00, $01, $01, $01, $01, $04, $01, $0C,
 // second half - NameChars
-$19, $03, $1A, $1B, $1C, $1D, $1E, $00,
-$00, $1F, $20, $21, $22, $23, $24, $25,
-$10, $11, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $00, $00, $12, $13,
-$26, $14, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $00, $00, $00, $00,
-$27, $16, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $00, $00, $01, $01,
+$03, $01, $01, $0A, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$0B, $07, $00, $00, $00, $00, $00, $00,
+$00, $00, $00, $00, $01, $01, $01, $05,
+$09, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
+$01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
@@ -225,17 +96,13 @@ $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
-$01, $01, $01, $01, $01, $01, $01, $17,
-$00, $00, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
 $01, $01, $01, $01, $01, $01, $01, $01,
-$01, $01, $01, $01, $01, $01, $01, $18,
 $00, $00, $00, $00, $00, $00, $00, $00,
 $00, $00, $00, $00, $00, $00, $00, $00,
 $00, $00, $00, $00, $00, $00, $00, $00,
 $00, $00, $00, $00, $00, $00, $00, $00,
-$00, $00, $00, $00, $00, $00, $00, $00);
+$00, $01, $01, $01, $01, $04, $01, $0C);
 

+ 14 - 26
packages/fcl-xml/src/xmlread.pp

@@ -282,7 +282,6 @@ type
     FName: TWideCharBuf;
     FTokenStart: TLocation;
     FStandalone: Boolean;
-    FNamePages: PByteArray;
     FDocType: TDTDModel;
     FPEMap: THashTable;
     FForwardRefs: TFPList;
@@ -321,7 +320,6 @@ type
     procedure EntityToSource(AEntity: TEntityDecl; out Src: TXMLCharSource);
     function ContextPush(AEntity: TEntityDecl): Boolean;
     function ContextPop(Forced: Boolean = False): Boolean;
-    procedure XML11_BuildTables;
     function ParseQuantity: TCPQuant;
     procedure StoreLocation(out Loc: TLocation);
     function ValidateAttrSyntax(AttrDef: TAttributeDef; const aValue: XMLString): Boolean;
@@ -817,7 +815,7 @@ begin
   end;
   FBufSize := 2047;
   if FReader.FXML11 then
-    FReader.XML11_BuildTables;
+    FXml11Rules := True;
 end;
 
 function TXMLDecodingSource.SetEncoding(const AEncoding: string): Boolean;
@@ -1148,8 +1146,8 @@ begin
       if FSource.FBuf > FSource.FBufEnd-2 then
         FSource.Reload;
 
-      if (not PercentAloneIsOk) or (Byte(FSource.FBuf[1]) in NamingBitmap[FNamePages^[$100+hi(Word(FSource.FBuf[1]))]]) or
-        (FXML11 and (FSource.FBuf[1] >= #$D800) and (FSource.FBuf[1] <= #$DB7F)) then
+      if (not PercentAloneIsOk) or (Byte(FSource.FBuf[1]) in NamingBitmap[NamePages[hi(Word(FSource.FBuf[1]))]]) or
+        ((FSource.FBuf[1] >= #$D800) and (FSource.FBuf[1] <= #$DB7F)) then
       begin
         Inc(FSource.FBuf);    // skip '%'
         CheckName;
@@ -1242,8 +1240,6 @@ begin
   FForwardRefs := TFPList.Create;
   FAttrChunks := TFPList.Create;
 
-  // Set char rules to XML 1.0
-  FNamePages := @NamePages;
   SetLength(FNodeStack, 16);
   SetLength(FValidators, 16);
 end;
@@ -1292,12 +1288,6 @@ begin
   inherited Destroy;
 end;
 
-procedure TXMLTextReader.XML11_BuildTables;
-begin
-  FNamePages := Xml11NamePages;
-  FXML11 := True;
-  FSource.FXml11Rules := True;
-end;
 
 { Must be executed after doc has been set.
   After introducing own NameTable, merge this into constructor }
@@ -1385,10 +1375,10 @@ begin
   repeat
     if NameStartFlag then
     begin
-      if (Byte(p^) in NamingBitmap[FNamePages^[hi(Word(p^))]]) or
+      if (Byte(p^) in NamingBitmap[NamePages[hi(Word(p^))]]) or
         ((p^ = ':') and (not FNamespaces)) then
         Inc(p)
-      else if FXML11 and ((p^ >= #$D800) and (p^ <= #$DB7F) and
+      else if ((p^ >= #$D800) and (p^ <= #$DB7F) and
         (p[1] >= #$DC00) and (p[1] <= #$DFFF)) then
         Inc(p, 2)
       else
@@ -1402,19 +1392,15 @@ begin
       NameStartFlag := False;
     end;
 
-    if FXML11 then
     repeat
-      if Byte(p^) in NamingBitmap[FNamePages^[$100+hi(Word(p^))]] then
+      if Byte(p^) in NamingBitmap[NamePages[$100+hi(Word(p^))]] then
         Inc(p)
       else if ((p^ >= #$D800) and (p^ <= #$DB7F) and
         (p[1] >= #$DC00) and (p[1] <= #$DFFF)) then
         Inc(p,2)
       else
         Break;
-    until False
-    else
-    while Byte(p^) in NamingBitmap[FNamePages^[$100+hi(Word(p^))]] do
-      Inc(p);
+    until False;
 
     if p^ = ':' then
     begin
@@ -1936,6 +1922,8 @@ begin
     ExpectString('version');
     ExpectEq;
     SkipQuote(Delim);
+    { !! Definition "VersionNum ::= '1.' [0-9]+" per XML 1.0 Fifth Edition
+      implies that version literal can have unlimited length. }
     I := 0;
     while (I < 3) and (FSource.FBuf^ <> Delim) do
     begin
@@ -1944,7 +1932,7 @@ begin
       FSource.NextChar;
     end;
     if (I <> 3) or (buf[0] <> '1') or (buf[1] <> '.') or
-      ((buf[2] <> '0') and (buf[2] <> '1')) then
+      (buf[2] < '0') or (buf[2] > '9') then
       FatalError('Illegal version number', -1);
 
     ExpectChar(Delim);
@@ -3560,12 +3548,12 @@ end;
 function TXMLTextReader.ValidateAttrSyntax(AttrDef: TAttributeDef; const aValue: XMLString): Boolean;
 begin
   case AttrDef.DataType of
-    dtId, dtIdRef, dtEntity: Result := IsXmlName(aValue, FXML11) and
+    dtId, dtIdRef, dtEntity: Result := IsXmlName(aValue) and
       ((not FNamespaces) or (Pos(WideChar(':'), aValue) = 0));
-    dtIdRefs, dtEntities: Result := IsXmlNames(aValue, FXML11) and
+    dtIdRefs, dtEntities: Result := IsXmlNames(aValue) and
       ((not FNamespaces) or (Pos(WideChar(':'), aValue) = 0));
-    dtNmToken: Result := IsXmlNmToken(aValue, FXML11) and AttrDef.HasEnumToken(aValue);
-    dtNmTokens: Result := IsXmlNmTokens(aValue, FXML11);
+    dtNmToken: Result := IsXmlNmToken(aValue) and AttrDef.HasEnumToken(aValue);
+    dtNmTokens: Result := IsXmlNmTokens(aValue);
     // IsXmlName() not necessary - enum is never empty and contains valid names
     dtNotation: Result := AttrDef.HasEnumToken(aValue);
   else

+ 11 - 75
packages/fcl-xml/src/xmlutils.pp

@@ -34,7 +34,7 @@ function IsXmlNames(const Value: XMLString; Xml11: Boolean = False): Boolean;
 function IsXmlNmToken(const Value: XMLString; Xml11: Boolean = False): Boolean;
 function IsXmlNmTokens(const Value: XMLString; Xml11: Boolean = False): Boolean;
 function IsValidXmlEncoding(const Value: XMLString): Boolean;
-function Xml11NamePages: PByteArray;
+
 procedure NormalizeSpaces(var Value: XMLString);
 function IsXmlWhiteSpace(c: WideChar): Boolean;
 function Hash(InitValue: LongWord; Key: PWideChar; KeyLen: Integer): LongWord;
@@ -231,37 +231,6 @@ function Decode_8859_1(Context: Pointer; InBuf: PChar; var InCnt: Cardinal; OutB
 
 implementation
 
-var
-  Xml11Pg: PByteArray = nil;
-
-function Xml11NamePages: PByteArray;
-var
-  I: Integer;
-  p: PByteArray;
-begin
-  if Xml11Pg = nil then
-  begin
-    GetMem(p, 512);
-    for I := 0 to 255 do
-      p^[I] := ord(Byte(I) in Xml11HighPages);
-    p^[0] := 2;
-    p^[3] := $2c;
-    p^[$20] := $2a;
-    p^[$21] := $2b;
-    p^[$2f] := $29;
-    p^[$30] := $2d;
-    p^[$fd] := $28;
-    p^[$ff] := $30;
-
-    Move(p^, p^[256], 256);
-    p^[$100] := $19;
-    p^[$103] := $2E;
-    p^[$120] := $2F;
-    Xml11Pg := p;
-  end;
-  Result := Xml11Pg;
-end;
-
 function IsXml11Char(Value: PWideChar; var Index: Integer): Boolean; overload;
 begin
   if (Value[Index] >= #$D800) and (Value[Index] <= #$DB7F) then
@@ -291,26 +260,18 @@ end;
 
 function IsXmlName(Value: PWideChar; Len: Integer; Xml11: Boolean = False): Boolean;
 var
-  Pages: PByteArray;
   I: Integer;
 begin
   Result := False;
-  if Xml11 then
-    Pages := Xml11NamePages
-  else
-    Pages := @NamePages;
-
   I := 0;
-  if (Len = 0) or not ((Byte(Value[I]) in NamingBitmap[Pages^[hi(Word(Value[I]))]]) or
-    (Value[I] = ':') or
-    (Xml11 and IsXml11Char(Value, I))) then
+  if (Len = 0) or not ((Byte(Value[I]) in NamingBitmap[NamePages[hi(Word(Value[I]))]]) or
+    (Value[I] = ':') or IsXml11Char(Value, I)) then
       Exit;
   Inc(I);
   while I < Len do
   begin
-    if not ((Byte(Value[I]) in NamingBitmap[Pages^[$100+hi(Word(Value[I]))]]) or
-      (Value[I] = ':') or
-      (Xml11 and IsXml11Char(Value, I))) then
+    if not ((Byte(Value[I]) in NamingBitmap[NamePages[$100+hi(Word(Value[I]))]]) or
+      (Value[I] = ':') or IsXml11Char(Value, I)) then
         Exit;
     Inc(I);
   end;
@@ -319,14 +280,9 @@ end;
 
 function IsXmlNames(const Value: XMLString; Xml11: Boolean): Boolean;
 var
-  Pages: PByteArray;
   I: Integer;
   Offset: Integer;
 begin
-  if Xml11 then
-    Pages := Xml11NamePages
-  else
-    Pages := @NamePages;
   Result := False;
   if Value = '' then
     Exit;
@@ -334,9 +290,8 @@ begin
   Offset := 0;
   while I <= Length(Value) do
   begin
-    if not ((Byte(Value[I]) in NamingBitmap[Pages^[Offset+hi(Word(Value[I]))]]) or
-      (Value[I] = ':') or
-      (Xml11 and IsXml11Char(Value, I))) then
+    if not ((Byte(Value[I]) in NamingBitmap[NamePages[Offset+hi(Word(Value[I]))]]) or
+      (Value[I] = ':') or IsXml11Char(Value, I)) then
     begin
       if (I = Length(Value)) or (Value[I] <> #32) then
         Exit;
@@ -353,21 +308,15 @@ end;
 function IsXmlNmToken(const Value: XMLString; Xml11: Boolean): Boolean;
 var
   I: Integer;
-  Pages: PByteArray;
 begin
-  if Xml11 then
-    Pages := Xml11NamePages
-  else
-    Pages := @NamePages;
   Result := False;
   if Value = '' then
     Exit;
   I := 1;
   while I <= Length(Value) do
   begin
-    if not ((Byte(Value[I]) in NamingBitmap[Pages^[$100+hi(Word(Value[I]))]]) or
-      (Value[I] = ':') or
-      (Xml11 and IsXml11Char(Value, I))) then
+    if not ((Byte(Value[I]) in NamingBitmap[NamePages[$100+hi(Word(Value[I]))]]) or
+      (Value[I] = ':') or IsXml11Char(Value, I)) then
         Exit;
     Inc(I);
   end;
@@ -377,21 +326,15 @@ end;
 function IsXmlNmTokens(const Value: XMLString; Xml11: Boolean): Boolean;
 var
   I: Integer;
-  Pages: PByteArray;
 begin
-  if Xml11 then
-    Pages := Xml11NamePages
-  else
-    Pages := @NamePages;
   I := 1;
   Result := False;
   if Value = '' then
     Exit;
   while I <= Length(Value) do
   begin
-    if not ((Byte(Value[I]) in NamingBitmap[Pages^[$100+hi(Word(Value[I]))]]) or
-      (Value[I] = ':') or
-      (Xml11 and IsXml11Char(Value, I))) then
+    if not ((Byte(Value[I]) in NamingBitmap[NamePages[$100+hi(Word(Value[I]))]]) or
+      (Value[I] = ':') or IsXml11Char(Value, I)) then
     begin
       if (I = Length(Value)) or (Value[I] <> #32) then
         Exit;
@@ -1161,11 +1104,4 @@ begin
   OutCnt := i;
 end;
 
-
-initialization
-
-finalization
-  if Assigned(Xml11Pg) then
-    FreeMem(Xml11Pg);
-
 end.

+ 3 - 1
packages/fcl-xml/tests/xmlts.pp

@@ -37,6 +37,8 @@ const
   parserName = parser;
   os = 'Unknown OS';
   runtime = 'FPC RTL';
+  { Defines which tests to skip (sets for editions 1-4 and edition 5 are mutually exclusive) }
+  FifthEditionCompliant = True;
 
 
 type
@@ -362,7 +364,7 @@ begin
   FTestID := Element['ID'];
   TestType := Element['TYPE'];
   xmlEdition := Element['EDITION'];
-  if (xmlEdition <> '') and (Pos(WideChar('5'), Element['EDITION']) > 0) then
+  if (xmlEdition <> '') and ((Pos(WideChar('5'), Element['EDITION']) = 0) = FifthEditionCompliant) then
   begin
     Inc(FSkipped);
     Exit;