Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Added text constraint command whitespace. |
---|---|
Downloads: | Tarball | ZIP archive | SQL archive |
Timelines: | family | ancestors | descendants | both | schema |
Files: | files | file ages | folders |
SHA3-256: |
567b33a968dac886c49fba7600674710 |
User & Date: | rolf 2020-06-27 00:09:17 |
Context
2020-07-03
| ||
11:56 | Merged from trunk. check-in: c8e5101f6a user: rolf tags: schema | |
2020-06-27
| ||
00:09 | Added text constraint command whitespace. check-in: 567b33a968 user: rolf tags: schema | |
00:07 | Fixed whitespaceImplReplace - correct mistakenly double test for \n and handle (the semi-hidden, because of the end-of-line handling by the parser) \r also. More tests. Closed-Leaf check-in: 2e024420ae user: rolf tags: xsdwhitespace | |
2020-06-11
| ||
00:52 | Merged from trunk. check-in: f782953f52 user: rolf tags: schema | |
Changes
Changes to doc/schema.xml.
793
794
795
796
797
798
799
800
801
802
803
804
805
806
...
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
|
is <m>tcl</m> everthing that returns TCL_OK if feeded into Tcl_GetInt() matches. If the optional argument to the command is <m>xsd</m> then the constraint match if the value is a valid xsd:integer. Without argument <m>xsd</m> is the default.</desc> </commanddef> <commanddef> <command><cmd>negativeInteger</cmd> <m>?(xsd|tcl)?</m></command> <desc>This text constraint match the same text values as the <m>integer</m> text constraint (see there) with the additional constraint that the value must be < zero.</desc> </commanddef> ................................................................................ <dt>whitespace</dt><dd>The text to split is striped of all white space at start and end splited into a list at any successive white space.</dd> <dt>tcl tclcmd ?arg ...?</dt><dd>The text to split is handed to the <m>tclcmd</m>, which is evaluated on global level, appended with every given arg and the text to split as last argument. This call must return a valid tcl list, which elements are tested..</dd> </dl> <p>The default in case no split type argument is given is <m>whitespace</m>.</p></desc> </commanddef> <commanddef> <command><cmd>id</cmd> <m>?keySpace?</m></command> <desc>This text constraint command marks the text as a |
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
...
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
|
is <m>tcl</m> everthing that returns TCL_OK if feeded into Tcl_GetInt() matches. If the optional argument to the command is <m>xsd</m> then the constraint match if the value is a valid xsd:integer. Without argument <m>xsd</m> is the default.</desc> </commanddef> <commanddef> <command><cmd>whitespace</cmd> <m>(preserve|replace|collapse)</m> <m><constraint script></m></command> <desc>This text constraint command does whitespace (#x20 (space, ' '), #x9 (tab, \t), #xA (linefeed, \n), and #xD (carriage return, \r) normalization to the text value and checks the resulting text with the text constraints of the constraint script argument. The normalization method <m>preserve</m> keeps everything as it is; this is another way to say <m>allOf</m>. The <m>replace</m> normalization method replaces any single whitespace character (as above) to a space. The <m>collapse</m> normalization method removes all leading and trailing whitespace and all the other sequences of contiguous whitespace are replaced by a single space.</desc> </commanddef> <commanddef> <command><cmd>negativeInteger</cmd> <m>?(xsd|tcl)?</m></command> <desc>This text constraint match the same text values as the <m>integer</m> text constraint (see there) with the additional constraint that the value must be < zero.</desc> </commanddef> ................................................................................ <dt>whitespace</dt><dd>The text to split is striped of all white space at start and end splited into a list at any successive white space.</dd> <dt>tcl tclcmd ?arg ...?</dt><dd>The text to split is handed to the <m>tclcmd</m>, which is evaluated on global level, appended with every given arg and the text to split as last argument. This call must return a valid tcl list, which elements are tested.</dd> </dl> <p>The default in case no split type argument is given is <m>whitespace</m>.</p></desc> </commanddef> <commanddef> <command><cmd>id</cmd> <m>?keySpace?</m></command> <desc>This text constraint command marks the text as a |
Changes to generic/schema.c.
80 81 82 83 84 85 86 87 88 89 90 91 92 93 ... 765 766 767 768 769 770 771 772 773 774 775 776 777 778 .... 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 .... 7977 7978 7979 7980 7981 7982 7983 7984 7985 7986 7987 7988 7989 7990 .... 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 |
#endif #ifndef URI_BUFFER_LEN_INIT # define URI_BUFFER_LEN_INIT 128 #endif #ifndef ATTR_ARRAY_INIT # define ATTR_ARRAY_INIT 4 #endif /*---------------------------------------------------------------------------- | Local defines | \---------------------------------------------------------------------------*/ #ifndef O_BINARY # ifdef _O_BINARY ................................................................................ ks = Tcl_GetHashValue (h); if (ks->active) { Tcl_DeleteHashTable (&ks->ids); } FREE (ks); } Tcl_DeleteHashTable (&sdata->keySpaces); FREE (sdata); } static void cleanupLastPattern ( SchemaData *sdata, unsigned int from ................................................................................ REMEMBER_PATTERN (pattern); Tcl_SetHashValue (h, pattern); } addToContent (sdata, pattern, quant, n, m); } else { /* Local definition of this element */ if (hnew) { pattern = initSchemaCP ( SCHEMA_CTYPE_NAME, sdata->currentNamespace, Tcl_GetHashKey (hashTable, h) ); pattern->flags |= PLACEHOLDER_PATTERN_DEF; REMEMBER_PATTERN (pattern); Tcl_SetHashValue (h, pattern); ................................................................................ checkNrArgs (2,2,"<tcl variable name>"); ADD_CONSTRAINT (sdata, sc) sc->constraint = setvarImpl; sc->freeData = setvarImplFree; sc->constraintData = tdomstrdup (Tcl_GetString (objv[1])); return TCL_OK; } void tDOM_SchemaInit ( Tcl_Interp *interp ) { Tcl_CreateObjCommand (interp, "tdom::schema", tDOM_SchemaObjCmd, ................................................................................ unsignedIntTypesTCObjCmd, (ClientData) 1, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::unsignedInt", unsignedIntTypesTCObjCmd, (ClientData) 2, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::unsignedLong", unsignedIntTypesTCObjCmd, (ClientData) 3, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::setvar", setvarTCObjCmd, (ClientData) 3, NULL); } #endif /* #ifndef TDOM_NO_SCHEMA */ |
> > > > > > | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 ... 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 .... 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 .... 7983 7984 7985 7986 7987 7988 7989 7990 7991 7992 7993 7994 7995 7996 7997 7998 7999 8000 8001 8002 8003 8004 8005 8006 8007 8008 8009 8010 8011 8012 8013 8014 8015 8016 8017 8018 8019 8020 8021 8022 8023 8024 8025 8026 8027 8028 8029 8030 8031 8032 8033 8034 8035 8036 8037 8038 8039 8040 8041 8042 8043 8044 8045 8046 8047 8048 8049 8050 8051 8052 8053 8054 8055 8056 8057 8058 8059 8060 8061 8062 8063 8064 8065 8066 8067 8068 8069 8070 8071 8072 8073 8074 8075 8076 8077 8078 8079 8080 8081 8082 8083 8084 8085 8086 8087 8088 8089 8090 8091 8092 8093 8094 8095 8096 8097 8098 8099 8100 8101 8102 8103 8104 8105 8106 8107 8108 8109 8110 8111 8112 8113 8114 8115 8116 8117 8118 8119 8120 8121 8122 8123 8124 8125 8126 8127 8128 8129 8130 8131 8132 8133 8134 8135 8136 8137 8138 8139 8140 8141 8142 8143 8144 8145 8146 8147 8148 8149 .... 8285 8286 8287 8288 8289 8290 8291 8292 8293 8294 8295 8296 8297 |
#endif #ifndef URI_BUFFER_LEN_INIT # define URI_BUFFER_LEN_INIT 128 #endif #ifndef ATTR_ARRAY_INIT # define ATTR_ARRAY_INIT 4 #endif #ifndef WHITESPACETC_BUFFER_LEN_INIT # define WHITESPACETC_BUFFER_LEN_INIT 200 #endif /*---------------------------------------------------------------------------- | Local defines | \---------------------------------------------------------------------------*/ #ifndef O_BINARY # ifdef _O_BINARY ................................................................................ ks = Tcl_GetHashValue (h); if (ks->active) { Tcl_DeleteHashTable (&ks->ids); } FREE (ks); } Tcl_DeleteHashTable (&sdata->keySpaces); if (sdata->wsbufLen) { FREE (sdata->wsbuf); } FREE (sdata); } static void cleanupLastPattern ( SchemaData *sdata, unsigned int from ................................................................................ REMEMBER_PATTERN (pattern); Tcl_SetHashValue (h, pattern); } addToContent (sdata, pattern, quant, n, m); } else { /* Local definition of this element */ if (hnew) { pattern = initSchemaCP( SCHEMA_CTYPE_NAME, sdata->currentNamespace, Tcl_GetHashKey (hashTable, h) ); pattern->flags |= PLACEHOLDER_PATTERN_DEF; REMEMBER_PATTERN (pattern); Tcl_SetHashValue (h, pattern); ................................................................................ checkNrArgs (2,2,"<tcl variable name>"); ADD_CONSTRAINT (sdata, sc) sc->constraint = setvarImpl; sc->freeData = setvarImplFree; sc->constraintData = tdomstrdup (Tcl_GetString (objv[1])); return TCL_OK; } typedef struct { SchemaCP *cp; SchemaData *sdata; } WhitespaceTCData; static void whitespaceImplFree ( void *constraintData ) { WhitespaceTCData *wsdata = (WhitespaceTCData *) constraintData; FREE (wsdata); } static int whitespaceImplReplace ( Tcl_Interp *interp, void *constraintData, char *text ) { WhitespaceTCData *wsdata = (WhitespaceTCData *) constraintData; char *p, *c, *alloced; SchemaData *sdata; sdata = wsdata->sdata; p = text; c = sdata->wsbuf; alloced = sdata->wsbuf + sdata->wsbufLen; while (*p) { if (*p == '\t' || *p == '\n' || *p == '\r') { *c = ' '; } else { *c = *p; } c++; if (c == alloced) { sdata->wsbuf = REALLOC (sdata->wsbuf, 2 * sdata->wsbufLen); c = sdata->wsbuf + sdata->wsbufLen; sdata->wsbufLen *= 2; alloced = sdata->wsbuf + sdata->wsbufLen; } p++; } *c = '\0'; return checkText (interp, wsdata->cp, sdata->wsbuf); } static int whitespaceImplCollapse ( Tcl_Interp *interp, void *constraintData, char *text ) { WhitespaceTCData *wsdata = (WhitespaceTCData *) constraintData; char *p, *c, *alloced; SchemaData *sdata; sdata = wsdata->sdata; p = text; c = sdata->wsbuf; alloced = sdata->wsbuf + sdata->wsbufLen; while (IS_XML_WHITESPACE(*p)) p++; while (*p) { if (IS_XML_WHITESPACE (*p)) { *c = ' '; c++; if (c == alloced) { sdata->wsbuf = REALLOC (sdata->wsbuf, 2 * sdata->wsbufLen); c = sdata->wsbuf + sdata->wsbufLen; sdata->wsbufLen *= 2; alloced = sdata->wsbuf + sdata->wsbufLen; } p++; while (IS_XML_WHITESPACE (*p)) p++; if (!*p) c--; } else { *c = *p; c++; if (c == alloced) { sdata->wsbuf = REALLOC (sdata->wsbuf, 2 * sdata->wsbufLen); c = sdata->wsbuf + sdata->wsbufLen; sdata->wsbufLen *= 2; alloced = sdata->wsbuf + sdata->wsbufLen; } p++; } } *c = '\0'; return checkText (interp, wsdata->cp, wsdata->sdata->wsbuf); } static int whitespaceTCObjCmd ( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[] ) { SchemaData *sdata = GETASI; SchemaCP *cp; SchemaConstraint *sc; int type; WhitespaceTCData *wsdata; static const char *types[] = { "preserve", "replace", "collapse", NULL }; enum typeSyms { t_preserve, t_replace, t_collapse }; CHECK_TI checkNrArgs (3,3,"(\"preserve\"|\"replace\"|\"collapse\") " "<text constraint script>"); if (Tcl_GetIndexFromObj (interp, objv[1], types, "type", 0, &type) != TCL_OK) { return TCL_ERROR; } cp = initSchemaCP (SCHEMA_CTYPE_CHOICE, NULL, NULL); cp->type = SCHEMA_CTYPE_TEXT; REMEMBER_PATTERN (cp) if (evalConstraints (interp, sdata, cp, objv[2]) != TCL_OK) { return TCL_ERROR; } if (type == t_preserve) { ADD_CONSTRAINT (sdata, sc) sc->constraint = checkText; sc->constraintData = (void *)cp; return TCL_OK; } ADD_CONSTRAINT (sdata, sc) sc->freeData = whitespaceImplFree; if (sdata->wsbufLen == 0) { sdata->wsbuf = (char *) MALLOC (WHITESPACETC_BUFFER_LEN_INIT); sdata->wsbufLen = WHITESPACETC_BUFFER_LEN_INIT; } wsdata = TMALLOC (WhitespaceTCData); wsdata->sdata = sdata; wsdata->cp = cp; sc->constraintData = (void *)wsdata; if (type == t_replace) { sc->constraint = whitespaceImplReplace; } else { sc->constraint = whitespaceImplCollapse; } return TCL_OK; } void tDOM_SchemaInit ( Tcl_Interp *interp ) { Tcl_CreateObjCommand (interp, "tdom::schema", tDOM_SchemaObjCmd, ................................................................................ unsignedIntTypesTCObjCmd, (ClientData) 1, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::unsignedInt", unsignedIntTypesTCObjCmd, (ClientData) 2, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::unsignedLong", unsignedIntTypesTCObjCmd, (ClientData) 3, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::setvar", setvarTCObjCmd, (ClientData) 3, NULL); Tcl_CreateObjCommand (interp,"tdom::schema::text::whitespace", whitespaceTCObjCmd, (ClientData) 3, NULL); } #endif /* #ifndef TDOM_NO_SCHEMA */ |
Changes to generic/schema.h.
194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
Tcl_HashTable idTables; Tcl_HashTable keySpaces; XML_Parser parser; domNode *node; domNode *insideNode; int choiceHashThreshold; int attributeHashThreshold; } SchemaData; int schemaInstanceCmd ( ClientData clientData, Tcl_Interp *interp, int objc, |
> > |
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
Tcl_HashTable idTables; Tcl_HashTable keySpaces; XML_Parser parser; domNode *node; domNode *insideNode; int choiceHashThreshold; int attributeHashThreshold; char *wsbuf; int wsbufLen; } SchemaData; int schemaInstanceCmd ( ClientData clientData, Tcl_Interp *interp, int objc, |
Changes to tests/schema.test.
5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 |
element a ! {text {setvar from_schema-14.44}} element b ! {text {setvar from_schema-14.44}} } set result [s validate "<doc><a>a</a><b>b</b></doc>"] s delete lappend result ${from_schema-14.44} } {1 b} test schema-15.1 {constraint cmd tcl} { tdom::schema s s define { defelement a { tcl append ::schema-15.1 [self] element b |
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841 5842 5843 5844 5845 5846 5847 5848 5849 5850 5851 5852 5853 5854 5855 5856 5857 5858 5859 5860 5861 5862 5863 5864 5865 5866 5867 5868 5869 5870 5871 5872 5873 5874 5875 5876 5877 5878 5879 5880 5881 5882 5883 5884 5885 5886 5887 5888 5889 5890 5891 5892 5893 5894 5895 5896 5897 5898 5899 5900 5901 5902 5903 5904 5905 5906 5907 5908 5909 5910 5911 5912 5913 5914 5915 5916 5917 5918 5919 5920 5921 5922 5923 5924 5925 |
element a ! {text {setvar from_schema-14.44}} element b ! {text {setvar from_schema-14.44}} } set result [s validate "<doc><a>a</a><b>b</b></doc>"] s delete lappend result ${from_schema-14.44} } {1 b} test schema-14.45 {text constraint whitespace} { tdom::schema s s defelement doc { text { whitespace preserve { oneOf { fixed foo allOf { minLength 5 integer } } } } } set result [list] foreach xml { <doc/> <doc></doc> <doc>foo</doc> <doc>12345</doc> <doc>1234</doc> <doc>1234a</doc> } { lappend result [s validate $xml] } s delete set result } {0 0 1 1 0 0} test schema-14.46 {text constraint whitespace} { tdom::schema s s defelement doc { text { whitespace replace { fixed "foo bar" } } } set result [list] foreach xml { <doc/> <doc></doc> {<doc>foo bar</doc>} {<doc>foo bar</doc>} {<doc>foo bar</doc>} {<doc>foo bar</doc>} } { lappend result [s validate $xml] } s delete set result } {0 0 1 1 1 0} test schema-14.47 {text constraint whitespace} { tdom::schema s s defelement doc { text { whitespace collapse { fixed "foo bar" } } } set result [list] foreach xml { <doc/> <doc></doc> {<doc>foo bar</doc>} {<doc>foo bar</doc>} {<doc>foo bar</doc>} {<doc>foo bar</doc>} {<doc> foo bar </doc>} {<doc> foo bar rr</doc>} } { lappend result [s validate $xml] } s delete set result } {0 0 1 1 1 1 1 0} test schema-14.48 {text constraint whitespace} { tdom::schema s s defelement doc { text { whitespace preserve { fixed "foo[string repeat " " 300]bar" } } } set xmls { <doc/> } lappend xmls "<doc>foo[string repeat " " 300]bar</doc>" set result [list] foreach xml $xmls { lappend result [s validate $xml] } s delete set result } {0 1} test schema-14.49 {text constraint whitespace} { tdom::schema s s defelement doc { text { whitespace collapse { fixed "foo [string repeat "x" 1200]bar" } } } set xmls { <doc/> } lappend xmls "<doc>[string repeat " " 300]foo[string repeat " " 300][string repeat "x" 1200]bar[string repeat " " 300]</doc>" set result [list] foreach xml $xmls { lappend result [s validate $xml] } s delete set result } {0 1} test schema-14.50 {text constraint whitespace} { tdom::schema s s defelement doc { element b ! { text { whitespace replace { fixed "foo[string repeat " " 400]bar" } } } } set xml <doc> append xml <b> foo [string repeat "
 \t
" 100] bar </b> append xml </doc> set result [s validate $xml] s delete set result } 1 test schema-14.51 {text constraint whitespace} { tdom::schema s s defelement doc { element a ! { text { whitespace collapse { fixed "foo [string repeat "x" 1200]bar" } } } element b ! { text { whitespace replace { fixed "foo[string repeat " " 8000]bar" } } } } set xml <doc> append xml <a> [string repeat " " 20] foo " " [string repeat x 1200] bar \ [string repeat " " 8000] </a> append xml <b> foo [string repeat "
 \t
" 2000] bar </b> append xml </doc> set result [s validate $xml] s delete set result } 1 test schema-15.1 {constraint cmd tcl} { tdom::schema s s define { defelement a { tcl append ::schema-15.1 [self] element b |