16
16
| Authors: Dave Barr <[email protected] > |
17
17
| Hannes Magnusson <[email protected] > |
18
18
| Gwynne Raskind <[email protected] > |
19
+ | André L F S Bacci <[email protected] > |
19
20
+----------------------------------------------------------------------+
20
21
*/
21
22
@@ -782,13 +783,15 @@ function dom_load( DOMDocument $dom , string $filename ) : bool
782
783
return $ dom ->load ( $ filename , $ options );
783
784
}
784
785
785
- function dom_saveload ( DOMDocument $ dom , string $ filename = "" )
786
+ function dom_saveload ( DOMDocument $ dom , string $ filename = "" ) : string
786
787
{
787
788
if ( $ filename == "" )
788
789
$ filename = __DIR__ . "/temp/manual.xml " ;
789
790
790
791
$ dom ->save ( $ filename );
791
792
dom_load ( $ dom , $ filename );
793
+
794
+ return $ filename ;
792
795
}
793
796
794
797
echo "Loading and parsing {$ ac ["INPUT_FILENAME " ]}... " ;
@@ -807,46 +810,140 @@ function dom_saveload( DOMDocument $dom , string $filename = "" )
807
810
808
811
809
812
echo "Running XInclude/XPointer... " ;
810
- $ total = 0 ;
811
- $ maxrun = 10 ; //LIBXML_VERSION >= 21100 ? 1 : 10;
812
- for ( $ run = 0 ; $ run < $ maxrun ; $ run ++ )
813
+
814
+ $ total = xinclude_run_byid ( $ dom );
815
+ $ total += xinclude_run_xpointer ( $ dom );
816
+
817
+ if ( $ total == 0 )
818
+ echo "failed. \n" ;
819
+ else
820
+ echo "done. Performed $ total XIncludes. \n" ;
821
+
822
+ xinclude_report ();
823
+ xinclude_residual ( $ dom );
824
+
825
+ function xinclude_run_byid ( DOMDocument $ dom )
813
826
{
814
- if ( $ run > 0 )
815
- echo "$ run " ;
816
- libxml_clear_errors ();
817
- $ status = (int ) $ dom ->xinclude ();
818
- if ( $ status <= 0 )
819
- break ;
820
- $ total += $ status ;
821
- if ( $ maxrun > 1 && $ run + 1 >= $ maxrun )
827
+ $ total = 0 ;
828
+ $ maxrun = 10 ; //LIBXML_VERSION >= 21100 ? 1 : 10;
829
+ for ( $ run = 0 ; $ run < $ maxrun ; $ run ++ )
822
830
{
823
- echo "Recursive XInclude is too deep. \n" ;
824
- errors_are_bad (-1 );
831
+ echo "$ run " ;
832
+ $ xpath = new DOMXPath ( $ dom );
833
+ $ xpath ->registerNamespace ( "xi " , "http://www.w3.org/2001/XInclude " );
834
+ $ xincludes = $ xpath ->query ( "//xi:include " );
835
+
836
+ $ changed = false ;
837
+ foreach ( $ xincludes as $ xinclude )
838
+ {
839
+ $ xpointer = $ xinclude ->getAttribute ( "xpointer " );
840
+ $ target = $ xinclude ->ownerDocument ->getElementById ( $ xpointer );
841
+
842
+ if ( $ target == null )
843
+ continue ;
844
+
845
+ $ other = new DOMDocument ( '1.0 ' , 'utf8 ' );
846
+ $ frags = $ other ->createDocumentFragment ();
847
+ $ other ->append ( $ frags );
848
+ $ frags ->append ( $ other ->importNode ( $ target , true ) ); // dup add
849
+
850
+ // "attributes in xml: namespace are not copied"
851
+
852
+ $ oxpth = new DOMXPath ( $ other );
853
+ $ attribs = $ oxpth ->query ( "//@* " );
854
+
855
+ foreach ( $ attribs as $ attrib )
856
+ if ( $ attrib ->prefix == "xml " )
857
+ $ attrib ->parentNode ->removeAttribute ( $ attrib ->nodeName );
858
+
859
+ $ insert = $ dom ->importNode ( $ frags , true ); // dup
860
+ $ xinclude ->parentNode ->insertBefore ( $ insert , $ xinclude ); // add
861
+ $ xinclude ->parentNode ->removeChild ( $ xinclude ); // del
862
+
863
+ $ total ++;
864
+ $ changed = true ;
865
+ libxml_clear_errors ();
866
+ }
867
+
868
+ if ( ! $ changed )
869
+ return $ total ;
825
870
}
871
+ echo "XInclude nested too deeply (xml:id). \n" ;
872
+ errors_are_bad ( 1 );
826
873
}
827
874
828
- if ($ total == 0 ) {
829
- echo "failed. \n" ;
830
- } else {
831
- echo "done. Performed $ total XIncludes. \n" ;
875
+ function xinclude_run_xpointer ( DOMDocument $ dom ) : int
876
+ {
877
+ $ total = 0 ;
878
+ $ maxrun = 10 ; //LIBXML_VERSION >= 21100 ? 1 : 10;
879
+ for ( $ run = 0 ; $ run < $ maxrun ; $ run ++ )
880
+ {
881
+ echo "$ run " ;
882
+ $ status = (int ) $ dom ->xinclude ();
883
+
884
+ if ( $ status <= 0 )
885
+ {
886
+ return $ total ;
887
+ }
888
+ $ total += $ status ;
889
+ libxml_clear_errors ();
890
+ }
891
+ echo "XInclude nested too deeply (xpointer). \n" ;
892
+ errors_are_bad ( 1 );
832
893
}
833
- flush ();
834
894
835
- if ( $ ac [ ' XPOINTER_REPORTING ' ] == ' yes ' || $ ac [ ' LANG ' ] == ' en ' )
895
+ function xinclude_report ( )
836
896
{
897
+ global $ ac ;
898
+
899
+ $ report = $ ac ['XPOINTER_REPORTING ' ] == 'yes ' || $ ac ['LANG ' ] == 'en ' ;
900
+ $ output = $ ac ['STDERR_TO_STDOUT ' ] == 'yes ' ? STDOUT : STDERR ;
901
+ $ fatal = $ ac ['LANG ' ] == 'en ' ;
902
+
837
903
$ errors = libxml_get_errors ();
838
- $ output = ( $ ac ['STDERR_TO_STDOUT ' ] == 'yes ' ) ? STDOUT : STDERR ;
839
- if ( count ( $ errors ) > 0 )
904
+ libxml_clear_errors ();
905
+
906
+ if ( ! $ report )
907
+ return ;
908
+
909
+ $ count = 0 ;
910
+ $ prefix = realpath ( __DIR__ );
911
+
912
+ $ prevLine = -1 ;
913
+ $ prevClmn = -1 ;
914
+
915
+ foreach ( $ errors as $ error )
840
916
{
841
- fprintf ( $ output , "\n" );
842
- foreach ( $ errors as $ error )
843
- fprintf ( $ output , "{$ error ->message }\n" );
844
- if ( $ ac ['LANG ' ] == 'en ' )
845
- errors_are_bad (1 );
917
+ $ msg = $ error ->message ;
918
+ $ file = $ error ->file ;
919
+ $ line = $ error ->line ;
920
+ $ clmn = $ error ->column ;
921
+
922
+ if ( $ prevLine == $ line && $ prevClmn == $ clmn )
923
+ continue ; // XPointer failures double reports sometimes
924
+ $ prevLine = $ line ;
925
+ $ prevClmn = $ clmn ;
926
+
927
+ $ msg = rtrim ( $ msg );
928
+ if ( str_starts_with ( $ file , $ prefix ) )
929
+ $ file = substr ( $ file , strlen ( $ prefix ) + 1 );
930
+
931
+ if ( $ count == 0 )
932
+ fprintf ( $ output , "\n" );
933
+
934
+ fprintf ( $ output , "[ {$ file } {$ line }: {$ clmn }] $ msg \n" );
935
+ $ count ++;
936
+ }
937
+
938
+ if ( $ count > 0 )
939
+ {
940
+ fprintf ( $ output , "\n" );
941
+ if ( $ fatal )
942
+ errors_are_bad ( 1 );
846
943
}
847
944
}
848
945
849
- if ( $ ac [ ' LANG ' ] != ' en ' )
946
+ function xinclude_residual ( DOMDocument $ dom )
850
947
{
851
948
// XInclude failures are soft errors on translations, so remove
852
949
// residual XInclude tags on translations to keep them building.
@@ -872,11 +969,11 @@ function dom_saveload( DOMDocument $dom , string $filename = "" )
872
969
case "tbody " :
873
970
$ fixup = "<row><entry></entry></row> " ;
874
971
break ;
875
- // case "variablelist":
876
- // $fixup = "<varlistentry><term> ></term><listitem><simpara></simpara></listitem></varlistentry>";
877
- // break;
972
+ case "variablelist " :
973
+ $ fixup = "<varlistentry><term></term><listitem><simpara></simpara></listitem></varlistentry> " ;
974
+ break ;
878
975
default :
879
- echo "Unknown parent element of failed XInclude: $ tagName \n" ;
976
+ echo "Unknown parent of failed XInclude: $ tagName \n" ;
880
977
$ explain = true ;
881
978
continue 2 ;
882
979
}
@@ -899,7 +996,25 @@ function dom_saveload( DOMDocument $dom , string $filename = "" )
899
996
state. Please report any "Unknown parent" messages on the doc-base
900
997
repository, and focus on fixing XInclude/XPointers failures above. \n\n
901
998
MSG ;
902
- exit (-1 ); // stop here, do not let more messages further confuse the matter
999
+ exit (1 ); // stop here, do not let more messages further confuse the matter
1000
+ }
1001
+
1002
+ // XInclude by xml:id never duplicates xml:id, horever, also using
1003
+ // XInclude by XPath/XPointer may start causing duplications
1004
+ // (see docs/structure.md). Crude and ugly fixup ahead, beware!
1005
+
1006
+ $ list = array ();
1007
+ $ nodes = $ xpath ->query ( "//*[@xml:id] " );
1008
+ foreach ( $ nodes as $ node )
1009
+ {
1010
+ $ id = $ node ->getAttribute ( "xml:id " );
1011
+ if ( isset ( $ list [ $ id ] ) )
1012
+ {
1013
+ if ( ! str_contains ( $ id , '.. ' ) )
1014
+ echo " Random removing duplicated xml:id: $ id \n" ;
1015
+ $ node ->removeAttribute ( "xml:id " );
1016
+ }
1017
+ $ list [ $ id ] = $ id ;
903
1018
}
904
1019
}
905
1020
@@ -1001,4 +1116,3 @@ function dom_saveload( DOMDocument $dom , string $filename = "" )
1001
1116
1002
1117
errors_are_bad (1 ); // Tell the shell that this script finished with an error.
1003
1118
}
1004
- ?>
0 commit comments