diff --git a/go.mod b/go.mod
index 3844230..8944643 100644
--- a/go.mod
+++ b/go.mod
@@ -6,25 +6,22 @@ require (
github.com/anthonynsimon/bild v0.13.0
github.com/fatih/color v1.16.0
github.com/stretchr/powerwalk v0.0.0-20151124150408-bceb9d014549
- github.com/urfave/cli v1.22.5
- github.com/xyproto/env/v2 v2.2.4
+ github.com/urfave/cli v1.22.14
+ github.com/xyproto/env/v2 v2.2.5
github.com/xyproto/heic v1.0.0
)
require (
- github.com/antchfx/xmlquery v1.3.8 // indirect
- github.com/antchfx/xpath v1.2.0 // indirect
- github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
+ github.com/antchfx/xmlquery v1.3.18 // indirect
+ github.com/antchfx/xpath v1.2.5 // indirect
+ github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
- github.com/russross/blackfriday/v2 v2.0.1 // indirect
- github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
- github.com/stretchr/testify v1.4.0 // indirect
- golang.org/x/image v0.13.0 // indirect
- golang.org/x/net v0.17.0 // indirect
- golang.org/x/sys v0.14.0 // indirect
- golang.org/x/text v0.13.0 // indirect
- gopkg.in/yaml.v2 v2.4.0 // indirect
- howett.net/plist v0.0.0-20201203080718-1454fab16a06 // indirect
+ github.com/russross/blackfriday/v2 v2.1.0 // indirect
+ golang.org/x/image v0.15.0 // indirect
+ golang.org/x/net v0.20.0 // indirect
+ golang.org/x/sys v0.16.0 // indirect
+ golang.org/x/text v0.14.0 // indirect
+ howett.net/plist v1.0.1 // indirect
)
diff --git a/go.sum b/go.sum
index 1abe28b..d6f3e64 100644
--- a/go.sum
+++ b/go.sum
@@ -1,8 +1,12 @@
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/antchfx/xmlquery v1.3.8 h1:dRnBQM3Vk5BVJFvFwsHOLAox+mEiNw5ZusaUNCrEdoU=
+github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/antchfx/xmlquery v1.3.8/go.mod h1:wojC/BxjEkjJt6dPiAqUzoXO5nIMWtxHS8PD8TmN4ks=
-github.com/antchfx/xpath v1.2.0 h1:mbwv7co+x0RwgeGAOHdrKy89GvHaGvxxBtPK0uF9Zr8=
+github.com/antchfx/xmlquery v1.3.18 h1:FSQ3wMuphnPPGJOFhvc+cRQ2CT/rUj4cyQXkJcjOwz0=
+github.com/antchfx/xmlquery v1.3.18/go.mod h1:Afkq4JIeXut75taLSuI31ISJ/zeq+3jG7TunF7noreA=
github.com/antchfx/xpath v1.2.0/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
+github.com/antchfx/xpath v1.2.4/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
+github.com/antchfx/xpath v1.2.5 h1:hqZ+wtQ+KIOV/S3bGZcIhpgYC26um2bZYP2KVGcR7VY=
+github.com/antchfx/xpath v1.2.5/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
github.com/anthonynsimon/bild v0.13.0 h1:mN3tMaNds1wBWi1BrJq0ipDBhpkooYfu7ZFSMhXt1C8=
github.com/anthonynsimon/bild v0.13.0/go.mod h1:tpzzp0aYkAsMi1zmfhimaDyX1xjn2OUc1AJZK/TF0AE=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
@@ -11,9 +15,9 @@ github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8Nz
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF22jk=
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
-github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
-github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
-github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
+github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
+github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
+github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -47,10 +51,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/russross/blackfriday v1.5.2 h1:HyvC0ARfnZBqnXwABFeSZHpKvJHJJfPz81GNueLj0oo=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
-github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
-github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
-github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
-github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
+github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
+github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
@@ -58,17 +60,21 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/powerwalk v0.0.0-20151124150408-bceb9d014549 h1:zjTKDjwZy1IVyLos+s70iYMwL/ZVojUbIDX5kghHa1Q=
github.com/stretchr/powerwalk v0.0.0-20151124150408-bceb9d014549/go.mod h1:RhJzAYfVBD/ULOCeUUaTn0CHDRQBYHjDY7yYpSt6+4M=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
-github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
+github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
+github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
-github.com/urfave/cli v1.22.5 h1:lNq9sAHXK2qfdI8W+GRItjCEkI+2oR4d+MEHy1CKXoU=
-github.com/urfave/cli v1.22.5/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
+github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
+github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
-github.com/xyproto/env/v2 v2.2.4 h1:Eysqz8rlZRBjKwH0a+oxyFj4WMDBaezKNHLx2S5f8go=
-github.com/xyproto/env/v2 v2.2.4/go.mod h1:F81ZEzu15s3TWUZJ1uzBl9iNeq9zcfHvxMkQJaLZUl0=
+github.com/xyproto/env/v2 v2.2.5 h1:FNrp56sptc7ebC2QpM8lqKSGEb3UoYUJZZFl4bmcrPs=
+github.com/xyproto/env/v2 v2.2.5/go.mod h1:F81ZEzu15s3TWUZJ1uzBl9iNeq9zcfHvxMkQJaLZUl0=
github.com/xyproto/heic v1.0.0 h1:42G/y7vACJbMvMfZmT7RmD9tbNixpLJ3Fc8zXOm6N7E=
github.com/xyproto/heic v1.0.0/go.mod h1:L/7tNatbi076v65zr94V5vGy96T9RusaMfjCS0dFQiU=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
@@ -76,10 +82,10 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
+golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
-golang.org/x/image v0.13.0 h1:3cge/F/QTkNLauhf2QoE9zp+7sr+ZcL4HnoZmdwg9sg=
-golang.org/x/image v0.13.0/go.mod h1:6mmbMOeV28HuMTgA6OSRkdXKYw/t5W9Uwn2Yv1r3Yxk=
+golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
+golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
@@ -89,9 +95,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20211111160137-58aab5ef257a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
-golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
-golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
+golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
+golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -110,22 +117,22 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
+golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
-golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
+golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@@ -133,9 +140,13 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v1 v1.0.0-20140924161607-9f9df34309c0/go.mod h1:WDnlLJ4WF5VGsH/HVa3CI79GS0ol3YnhVnKP89i0kNg=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
-howett.net/plist v0.0.0-20201203080718-1454fab16a06 h1:QDxUo/w2COstK1wIBYpzQlHX/NqaQTcf9jyz347nI58=
+gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
+gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
howett.net/plist v0.0.0-20201203080718-1454fab16a06/go.mod h1:vMygbs4qMhSZSc4lCUl2OEE+rDiIIJAIdR4m7MiMcm0=
+howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
+howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
diff --git a/vendor/github.com/antchfx/xmlquery/README.md b/vendor/github.com/antchfx/xmlquery/README.md
index bae7fc3..11fafde 100644
--- a/vendor/github.com/antchfx/xmlquery/README.md
+++ b/vendor/github.com/antchfx/xmlquery/README.md
@@ -15,26 +15,13 @@ data or evaluate from XML documents with an XPath expression.
XPATH query strings. Enabling caching can avoid recompile XPath expression for
each query.
-Change Logs
-===
-
-2020-08-??
-- Add XML stream loading and parsing support.
+You can visit this page to learn about the supported XPath(1.0/2.0) syntax. https://github.com/antchfx/xpath
-2019-11-11
-- Add XPath query caching.
+[htmlquery](https://github.com/antchfx/htmlquery) - Package for the HTML document query.
-2019-10-05
-- Add new methods compatible with invalid XPath expression error: `QueryAll` and `Query`.
-- Add `QuerySelector` and `QuerySelectorAll` methods, support for reused query objects.
-- PR [#12](https://github.com/antchfx/xmlquery/pull/12) (Thanks @FrancescoIlario)
-- PR [#11](https://github.com/antchfx/xmlquery/pull/11) (Thanks @gjvnq)
+[xmlquery](https://github.com/antchfx/xmlquery) - Package for the XML document query.
-2018-12-23
-- Added XML output including comment nodes. [#9](https://github.com/antchfx/xmlquery/issues/9)
-
-2018-12-03
-- Added support to attribute name with namespace prefix and XML output. [#6](https://github.com/antchfx/xmlquery/issues/6)
+[jsonquery](https://github.com/antchfx/jsonquery) - Package for the JSON document query.
Installation
====
@@ -42,6 +29,52 @@ Installation
$ go get github.com/antchfx/xmlquery
```
+
+Quick Starts
+===
+
+```go
+import (
+ "github.com/antchfx/xmlquery"
+)
+
+func main(){
+ s := `
+
+
+ W3Schools Home Page
+ https://www.w3schools.com
+ Free web building tutorials
+ -
+ RSS Tutorial
+ https://www.w3schools.com/xml/xml_rss.asp
+ New RSS tutorial on W3Schools
+
+ -
+ XML Tutorial
+ https://www.w3schools.com/xml
+ New XML tutorial on W3Schools
+
+
+`
+
+ doc, err := xmlquery.Parse(strings.NewReader(s))
+ if err != nil {
+ panic(err)
+ }
+ channel := xmlquery.FindOne(doc, "//channel")
+ if n := channel.SelectElement("title"); n != nil {
+ fmt.Printf("title: %s\n", n.InnerText())
+ }
+ if n := channel.SelectElement("link"); n != nil {
+ fmt.Printf("link: %s\n", n.InnerText())
+ }
+ for i, n := range xmlquery.Find(doc, "//item/title") {
+ fmt.Printf("#%d %s\n", i, n.InnerText())
+ }
+}
+```
+
Getting Started
===
@@ -77,7 +110,7 @@ doc, err := xmlquery.Parse(f)
#### Parse an XML in a stream fashion (simple case without elements filtering).
```go
-f, err := os.Open("../books.xml")
+f, _ := os.Open("../books.xml")
p, err := xmlquery.CreateStreamParser(f, "/bookstore/book")
for {
n, err := p.Read()
@@ -85,15 +118,18 @@ for {
break
}
if err != nil {
- ...
+ panic(err)
}
+ fmt.Println(n)
}
```
+Notes: `CreateStreamParser()` used for saving memory if your had a large XML file to parse.
+
#### Parse an XML in a stream fashion (simple case advanced element filtering).
```go
-f, err := os.Open("../books.xml")
+f, _ := os.Open("../books.xml")
p, err := xmlquery.CreateStreamParser(f, "/bookstore/book", "/bookstore/book[price>=10]")
for {
n, err := p.Read()
@@ -101,8 +137,9 @@ for {
break
}
if err != nil {
- ...
+ panic(err)
}
+ fmt.Println(n)
}
```
@@ -153,24 +190,49 @@ expr, err := xpath.Compile("count(//book)")
price := expr.Evaluate(xmlquery.CreateXPathNavigator(doc)).(float64)
```
-FAQ
+Advanced Features
====
-#### `Find()` vs `QueryAll()`, which is better?
-
-`Find` and `QueryAll` both do the same thing: searches all of matched XML nodes.
-`Find` panics if provided with an invalid XPath query, while `QueryAll` returns
-an error.
+### Parse `UTF-16` XML file with `ParseWithOptions()`.
-#### Can I save my query expression object for the next query?
+```go
+f, _ := os.Open(`UTF-16.XML`)
+// Convert UTF-16 XML to UTF-8
+utf16ToUtf8Transformer := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM).NewDecoder()
+utf8Reader := transform.NewReader(f, utf16ToUtf8Transformer)
+// Sets `CharsetReader`
+options := xmlquery.ParserOptions{
+ Decoder: &xmlquery.DecoderOptions{
+ CharsetReader: func(charset string, input io.Reader) (io.Reader, error) {
+ return input, nil
+ },
+ },
+}
+doc, err := xmlquery.ParseWithOptions(utf8Reader, options)
+```
-Yes, you can. We provide `QuerySelector` and `QuerySelectorAll` methods; they
-accept your query expression object.
+### Query with custom namespace prefix.
-Caching a query expression object avoids recompiling the XPath query
-expression, improving query performance.
+```go
+s := `
+
+
+RequestReplyActivity
+OpClientReqActivity
+300
+80
+
+`
+nsMap := map[string]string{
+ "q": "http://xmlns.xyz.com/process/2003",
+ "r": "http://www.w3.org/1999/XSL/Transform",
+ "s": "http://www.w3.org/2001/XMLSchema",
+}
+expr, _ := xpath.CompileWithNS("//q:activity", nsMap)
+node := xmlquery.QuerySelector(doc, expr)
+```
-#### Create XML document.
+#### Create XML document without call `xml.Marshal`.
```go
doc := &xmlquery.Node{
@@ -200,63 +262,34 @@ title_text := &xmlquery.Node{
}
title.FirstChild = title_text
channel.FirstChild = title
+
fmt.Println(doc.OutputXML(true))
-// W3Schools Home Page
+fmt.Println(doc.OutputXMLWithOptions(WithOutputSelf()))
```
-Quick Tutorial
-===
+Output:
-```go
-import (
- "github.com/antchfx/xmlquery"
-)
+```xml
+W3Schools Home Page
+```
-func main(){
- s := `
-
-
- W3Schools Home Page
- https://www.w3schools.com
- Free web building tutorials
- -
- RSS Tutorial
- https://www.w3schools.com/xml/xml_rss.asp
- New RSS tutorial on W3Schools
-
- -
- XML Tutorial
- https://www.w3schools.com/xml
- New XML tutorial on W3Schools
-
-
-`
+FAQ
+====
- doc, err := xmlquery.Parse(strings.NewReader(s))
- if err != nil {
- panic(err)
- }
- channel := xmlquery.FindOne(doc, "//channel")
- if n := channel.SelectElement("title"); n != nil {
- fmt.Printf("title: %s\n", n.InnerText())
- }
- if n := channel.SelectElement("link"); n != nil {
- fmt.Printf("link: %s\n", n.InnerText())
- }
- for i, n := range xmlquery.Find(doc, "//item/title") {
- fmt.Printf("#%d %s\n", i, n.InnerText())
- }
-}
-```
+#### `Find()` vs `QueryAll()`, which is better?
-List of supported XPath query packages
-===
-| Name | Description |
-| ------------------------------------------------- | ----------------------------------------- |
-| [htmlquery](https://github.com/antchfx/htmlquery) | XPath query package for HTML documents |
-| [xmlquery](https://github.com/antchfx/xmlquery) | XPath query package for XML documents |
-| [jsonquery](https://github.com/antchfx/jsonquery) | XPath query package for JSON documents |
+`Find` and `QueryAll` both do the same thing: searches all of matched XML nodes.
+`Find` panics if provided with an invalid XPath query, while `QueryAll` returns
+an error.
+
+#### Can I save my query expression object for the next query?
+
+Yes, you can. We provide `QuerySelector` and `QuerySelectorAll` methods; they
+accept your query expression object.
+
+Caching a query expression object avoids recompiling the XPath query
+expression, improving query performance.
- Questions
+Questions
===
Please let me know if you have any questions
diff --git a/vendor/github.com/antchfx/xmlquery/node.go b/vendor/github.com/antchfx/xmlquery/node.go
index be6e31a..207892a 100644
--- a/vendor/github.com/antchfx/xmlquery/node.go
+++ b/vendor/github.com/antchfx/xmlquery/node.go
@@ -1,9 +1,9 @@
package xmlquery
import (
- "bytes"
"encoding/xml"
"fmt"
+ "html"
"strings"
)
@@ -49,24 +49,74 @@ type Node struct {
level int // node level in the tree
}
+type outputConfiguration struct {
+ printSelf bool
+ preserveSpaces bool
+ emptyElementTagSupport bool
+ skipComments bool
+}
+
+type OutputOption func(*outputConfiguration)
+
+// WithOutputSelf configures the Node to print the root node itself
+func WithOutputSelf() OutputOption {
+ return func(oc *outputConfiguration) {
+ oc.printSelf = true
+ }
+}
+
+// WithEmptyTagSupport empty tags should be written as and
+// not as
+func WithEmptyTagSupport() OutputOption {
+ return func(oc *outputConfiguration) {
+ oc.emptyElementTagSupport = true
+ }
+}
+
+// WithoutComments will skip comments in output
+func WithoutComments() OutputOption {
+ return func(oc *outputConfiguration) {
+ oc.skipComments = true
+ }
+}
+
+// WithPreserveSpace will preserve spaces in output
+func WithPreserveSpace() OutputOption {
+ return func(oc *outputConfiguration) {
+ oc.preserveSpaces = true
+ }
+}
+
+func newXMLName(name string) xml.Name {
+ if i := strings.IndexByte(name, ':'); i > 0 {
+ return xml.Name{
+ Space: name[:i],
+ Local: name[i+1:],
+ }
+ }
+ return xml.Name{
+ Local: name,
+ }
+}
+
// InnerText returns the text between the start and end tags of the object.
func (n *Node) InnerText() string {
- var output func(*bytes.Buffer, *Node)
- output = func(buf *bytes.Buffer, n *Node) {
+ var output func(*strings.Builder, *Node)
+ output = func(b *strings.Builder, n *Node) {
switch n.Type {
case TextNode, CharDataNode:
- buf.WriteString(n.Data)
+ b.WriteString(n.Data)
case CommentNode:
default:
for child := n.FirstChild; child != nil; child = child.NextSibling {
- output(buf, child)
+ output(b, child)
}
}
}
- var buf bytes.Buffer
- output(&buf, n)
- return buf.String()
+ var b strings.Builder
+ output(&b, n)
+ return b.String()
}
func (n *Node) sanitizedData(preserveSpaces bool) string {
@@ -85,92 +135,141 @@ func calculatePreserveSpaces(n *Node, pastValue bool) bool {
return pastValue
}
-func outputXML(buf *bytes.Buffer, n *Node, preserveSpaces bool) {
+func outputXML(b *strings.Builder, n *Node, preserveSpaces bool, config *outputConfiguration) {
preserveSpaces = calculatePreserveSpaces(n, preserveSpaces)
switch n.Type {
case TextNode:
- xml.EscapeText(buf, []byte(n.sanitizedData(preserveSpaces)))
+ b.WriteString(html.EscapeString(n.sanitizedData(preserveSpaces)))
return
case CharDataNode:
- buf.WriteString("")
+ b.WriteString("")
return
case CommentNode:
- buf.WriteString("")
+ if !config.skipComments {
+ b.WriteString("")
+ }
return
case DeclarationNode:
- buf.WriteString("" + n.Data)
+ b.WriteString("" + n.Data)
default:
if n.Prefix == "" {
- buf.WriteString("<" + n.Data)
+ b.WriteString("<" + n.Data)
} else {
- buf.WriteString("<" + n.Prefix + ":" + n.Data)
+ fmt.Fprintf(b, "<%s:%s", n.Prefix, n.Data)
}
}
for _, attr := range n.Attr {
if attr.Name.Space != "" {
- buf.WriteString(fmt.Sprintf(` %s:%s=`, attr.Name.Space, attr.Name.Local))
+ fmt.Fprintf(b, ` %s:%s=`, attr.Name.Space, attr.Name.Local)
} else {
- buf.WriteString(fmt.Sprintf(` %s=`, attr.Name.Local))
+ fmt.Fprintf(b, ` %s=`, attr.Name.Local)
}
- buf.WriteByte('"')
- xml.EscapeText(buf, []byte(attr.Value))
- buf.WriteByte('"')
+ b.WriteByte('"')
+ b.WriteString(html.EscapeString(attr.Value))
+ b.WriteByte('"')
}
if n.Type == DeclarationNode {
- buf.WriteString("?>")
+ b.WriteString("?>")
} else {
- buf.WriteString(">")
+ if n.FirstChild != nil || !config.emptyElementTagSupport {
+ b.WriteString(">")
+ } else {
+ b.WriteString("/>")
+ return
+ }
}
for child := n.FirstChild; child != nil; child = child.NextSibling {
- outputXML(buf, child, preserveSpaces)
+ outputXML(b, child, preserveSpaces, config)
}
if n.Type != DeclarationNode {
if n.Prefix == "" {
- buf.WriteString(fmt.Sprintf("%s>", n.Data))
+ fmt.Fprintf(b, "%s>", n.Data)
} else {
- buf.WriteString(fmt.Sprintf("%s:%s>", n.Prefix, n.Data))
+ fmt.Fprintf(b, "%s:%s>", n.Prefix, n.Data)
}
}
}
// OutputXML returns the text that including tags name.
func (n *Node) OutputXML(self bool) string {
+
+ config := &outputConfiguration{
+ printSelf: true,
+ emptyElementTagSupport: false,
+ }
preserveSpaces := calculatePreserveSpaces(n, false)
- var buf bytes.Buffer
- if self {
- outputXML(&buf, n, preserveSpaces)
+ var b strings.Builder
+ if self && n.Type != DocumentNode {
+ outputXML(&b, n, preserveSpaces, config)
} else {
for n := n.FirstChild; n != nil; n = n.NextSibling {
- outputXML(&buf, n, preserveSpaces)
+ outputXML(&b, n, preserveSpaces, config)
}
}
- return buf.String()
+ return b.String()
}
-// AddAttr adds a new attribute specified by 'key' and 'val' to a node 'n'.
-func AddAttr(n *Node, key, val string) {
- var attr Attr
- if i := strings.Index(key, ":"); i > 0 {
- attr = Attr{
- Name: xml.Name{Space: key[:i], Local: key[i+1:]},
- Value: val,
- }
+// OutputXMLWithOptions returns the text that including tags name.
+func (n *Node) OutputXMLWithOptions(opts ...OutputOption) string {
+
+ config := &outputConfiguration{}
+ // Set the options
+ for _, opt := range opts {
+ opt(config)
+ }
+ pastPreserveSpaces := config.preserveSpaces
+ preserveSpaces := calculatePreserveSpaces(n, pastPreserveSpaces)
+ var b strings.Builder
+ if config.printSelf && n.Type != DocumentNode {
+ outputXML(&b, n, preserveSpaces, config)
} else {
- attr = Attr{
- Name: xml.Name{Local: key},
- Value: val,
+ for n := n.FirstChild; n != nil; n = n.NextSibling {
+ outputXML(&b, n, preserveSpaces, config)
}
}
+ return b.String()
+}
+
+// AddAttr adds a new attribute specified by 'key' and 'val' to a node 'n'.
+func AddAttr(n *Node, key, val string) {
+ attr := Attr{
+ Name: newXMLName(key),
+ Value: val,
+ }
n.Attr = append(n.Attr, attr)
}
+// SetAttr allows an attribute value with the specified name to be changed.
+// If the attribute did not previously exist, it will be created.
+func (n *Node) SetAttr(key, value string) {
+ name := newXMLName(key)
+ for i, attr := range n.Attr {
+ if attr.Name == name {
+ n.Attr[i].Value = value
+ return
+ }
+ }
+ AddAttr(n, key, value)
+}
+
+// RemoveAttr removes the attribute with the specified name.
+func (n *Node) RemoveAttr(key string) {
+ name := newXMLName(key)
+ for i, attr := range n.Attr {
+ if attr.Name == name {
+ n.Attr = append(n.Attr[:i], n.Attr[i+1:]...)
+ return
+ }
+ }
+}
+
// AddChild adds a new node 'n' to a node 'parent' as its last child.
func AddChild(parent, n *Node) {
n.Parent = parent
diff --git a/vendor/github.com/antchfx/xmlquery/options.go b/vendor/github.com/antchfx/xmlquery/options.go
index f3e2f99..6b902d2 100644
--- a/vendor/github.com/antchfx/xmlquery/options.go
+++ b/vendor/github.com/antchfx/xmlquery/options.go
@@ -2,9 +2,10 @@ package xmlquery
import (
"encoding/xml"
+ "io"
)
-type ParserOptions struct{
+type ParserOptions struct {
Decoder *DecoderOptions
}
@@ -17,14 +18,16 @@ func (options ParserOptions) apply(parser *parser) {
// DecoderOptions implement the very same options than the standard
// encoding/xml package. Please refer to this documentation:
// https://golang.org/pkg/encoding/xml/#Decoder
-type DecoderOptions struct{
- Strict bool
- AutoClose []string
- Entity map[string]string
+type DecoderOptions struct {
+ Strict bool
+ AutoClose []string
+ Entity map[string]string
+ CharsetReader func(charset string, input io.Reader) (io.Reader, error)
}
func (options DecoderOptions) apply(decoder *xml.Decoder) {
decoder.Strict = options.Strict
decoder.AutoClose = options.AutoClose
decoder.Entity = options.Entity
+ decoder.CharsetReader = options.CharsetReader
}
diff --git a/vendor/github.com/antchfx/xmlquery/parse.go b/vendor/github.com/antchfx/xmlquery/parse.go
index 810eb73..fe3de99 100644
--- a/vendor/github.com/antchfx/xmlquery/parse.go
+++ b/vendor/github.com/antchfx/xmlquery/parse.go
@@ -3,7 +3,6 @@ package xmlquery
import (
"bufio"
"encoding/xml"
- "errors"
"fmt"
"io"
"net/http"
@@ -53,7 +52,6 @@ func ParseWithOptions(r io.Reader, options ParserOptions) (*Node, error) {
type parser struct {
decoder *xml.Decoder
doc *Node
- space2prefix map[string]string
level int
prev *Node
streamElementXPath *xpath.Expr // Under streaming mode, this specifies the xpath to the target element node(s).
@@ -66,24 +64,26 @@ type parser struct {
func createParser(r io.Reader) *parser {
reader := newCachedReader(bufio.NewReader(r))
p := &parser{
- decoder: xml.NewDecoder(reader),
- doc: &Node{Type: DocumentNode},
- space2prefix: make(map[string]string),
- level: 0,
- reader: reader,
+ decoder: xml.NewDecoder(reader),
+ doc: &Node{Type: DocumentNode},
+ level: 0,
+ reader: reader,
+ }
+ if p.decoder.CharsetReader == nil {
+ p.decoder.CharsetReader = charset.NewReaderLabel
}
- // http://www.w3.org/XML/1998/namespace is bound by definition to the prefix xml.
- p.space2prefix["http://www.w3.org/XML/1998/namespace"] = "xml"
- p.decoder.CharsetReader = charset.NewReaderLabel
p.prev = p.doc
return p
}
func (p *parser) parse() (*Node, error) {
var streamElementNodeCounter int
+ space2prefix := map[string]string{"http://www.w3.org/XML/1998/namespace": "xml"}
for {
+ p.reader.StartCaching()
tok, err := p.decoder.Token()
+ p.reader.StopCaching()
if err != nil {
return nil, err
}
@@ -92,30 +92,40 @@ func (p *parser) parse() (*Node, error) {
case xml.StartElement:
if p.level == 0 {
// mising XML declaration
- node := &Node{Type: DeclarationNode, Data: "xml", level: 1}
+ attributes := make([]Attr, 1)
+ attributes[0].Name = xml.Name{Local: "version"}
+ attributes[0].Value = "1.0"
+ node := &Node{
+ Type: DeclarationNode,
+ Data: "xml",
+ Attr: attributes,
+ level: 1,
+ }
AddChild(p.prev, node)
p.level = 1
p.prev = node
}
- // https://www.w3.org/TR/xml-names/#scoping-defaulting
+
for _, att := range tok.Attr {
if att.Name.Local == "xmlns" {
- p.space2prefix[att.Value] = ""
+ space2prefix[att.Value] = "" // reset empty if exist the default namespace
+ // defaultNamespaceURL = att.Value
} else if att.Name.Space == "xmlns" {
- p.space2prefix[att.Value] = att.Name.Local
+ // maybe there are have duplicate NamespaceURL?
+ space2prefix[att.Value] = att.Name.Local
}
}
- if tok.Name.Space != "" {
- if _, found := p.space2prefix[tok.Name.Space]; !found {
- return nil, errors.New("xmlquery: invalid XML document, namespace is missing")
+ if space := tok.Name.Space; space != "" {
+ if _, found := space2prefix[space]; !found && p.decoder.Strict {
+ return nil, fmt.Errorf("xmlquery: invalid XML document, namespace %s is missing", space)
}
}
attributes := make([]Attr, len(tok.Attr))
for i, att := range tok.Attr {
name := att.Name
- if prefix, ok := p.space2prefix[name.Space]; ok {
+ if prefix, ok := space2prefix[name.Space]; ok {
name.Space = prefix
}
attributes[i] = Attr{
@@ -128,7 +138,6 @@ func (p *parser) parse() (*Node, error) {
node := &Node{
Type: ElementNode,
Data: tok.Name.Local,
- Prefix: p.space2prefix[tok.Name.Space],
NamespaceURI: tok.Name.Space,
Attr: attributes,
level: p.level,
@@ -144,6 +153,15 @@ func (p *parser) parse() (*Node, error) {
}
AddSibling(p.prev.Parent, node)
}
+
+ if node.NamespaceURI != "" {
+ if v, ok := space2prefix[node.NamespaceURI]; ok {
+ cached := string(p.reader.Cache())
+ if strings.HasPrefix(cached, fmt.Sprintf("%s:%s", v, node.Data)) || strings.HasPrefix(cached, fmt.Sprintf("<%s:%s", v, node.Data)) {
+ node.Prefix = v
+ }
+ }
+ }
// If we're in the streaming mode, we need to remember the node if it is the target node
// so that when we finish processing the node's EndElement, we know how/what to return to
// caller. Also we need to remove the target node from the tree upon next Read() call so
@@ -161,7 +179,6 @@ func (p *parser) parse() (*Node, error) {
}
p.prev = node
p.level++
- p.reader.StartCaching()
case xml.EndElement:
p.level--
// If we're in streaming mode, and we already have a potential streaming
@@ -198,11 +215,10 @@ func (p *parser) parse() (*Node, error) {
}
}
case xml.CharData:
- p.reader.StopCaching()
// First, normalize the cache...
cached := strings.ToUpper(string(p.reader.Cache()))
nodeType := TextNode
- if strings.HasPrefix(cached, " p.prev.level {
AddChild(p.prev, node)
+ } else if p.level < p.prev.level {
+ for i := p.prev.level - p.level; i > 1; i-- {
+ p.prev = p.prev.Parent
+ }
+ AddSibling(p.prev.Parent, node)
}
p.prev = node
case xml.Directive:
@@ -307,7 +327,7 @@ type StreamParser struct {
// streamElementFilter, if provided, cannot be successfully parsed and compiled
// into a valid xpath query.
func CreateStreamParser(r io.Reader, streamElementXPath string, streamElementFilter ...string) (*StreamParser, error) {
- return CreateStreamParserWithOptions(r, ParserOptions{}, streamElementXPath, streamElementFilter...)
+ return CreateStreamParserWithOptions(r, ParserOptions{}, streamElementXPath, streamElementFilter...)
}
// CreateStreamParserWithOptions is like CreateStreamParser, but with custom options
diff --git a/vendor/github.com/antchfx/xmlquery/query.go b/vendor/github.com/antchfx/xmlquery/query.go
index 0bd45dd..9f2493f 100644
--- a/vendor/github.com/antchfx/xmlquery/query.go
+++ b/vendor/github.com/antchfx/xmlquery/query.go
@@ -28,14 +28,9 @@ func (n *Node) SelectAttr(name string) string {
}
return ""
}
- var local, space string
- local = name
- if i := strings.Index(name, ":"); i > 0 {
- space = name[:i]
- local = name[i+1:]
- }
+ xmlName := newXMLName(name)
for _, attr := range n.Attr {
- if attr.Name.Local == local && attr.Name.Space == space {
+ if attr.Name == xmlName {
return attr.Value
}
}
diff --git a/vendor/github.com/antchfx/xpath/README.md b/vendor/github.com/antchfx/xpath/README.md
index 9a58a9f..d1e3a3c 100644
--- a/vendor/github.com/antchfx/xpath/README.md
+++ b/vendor/github.com/antchfx/xpath/README.md
@@ -49,7 +49,7 @@ Supported Features
- `a/b` : For each node matching a, add the nodes matching b to the result.
-- `a//b` : For each node matching a, add the descendant nodes matching b to the result.
+- `a//b` : For each node matching a, add the descendant nodes matching b to the result.
- `//b` : Returns elements in the entire document matching b.
@@ -57,8 +57,9 @@ Supported Features
- `(a, b, c)` : Evaluates each of its operands and concatenates the resulting sequences, in order, into a single result sequence
+- `(a/b)` : Selects all matches nodes as grouping set.
-#### Node Axes
+#### Node Axes
- `child::*` : The child axis selects children of the current node.
@@ -72,9 +73,9 @@ Supported Features
- `preceding-sibling::*` : Selects nodes before the current node.
-- `following::*` : Selects the first matching node following in document order, excluding descendants.
+- `following::*` : Selects the first matching node following in document order, excluding descendants.
-- `preceding::*` : Selects the first matching node preceding in document order, excluding ancestors.
+- `preceding::*` : Selects the first matching node preceding in document order, excluding ancestors.
- `parent::*` : Selects the parent if it matches. The '..' pattern from the core is equivalent to 'parent::node()'.
@@ -150,6 +151,7 @@ Supported Features
`round()`| ✓ |
`starts-with()`| ✓ |
`string()`| ✓ |
+`string-join()`[^1]| ✓ |
`string-length()`| ✓ |
`substring()`| ✓ |
`substring-after()`| ✓ |
@@ -160,14 +162,4 @@ Supported Features
`true()`| ✓ |
`unparsed-entity-url()` | ✗ |
-Changelogs
-===
-
-2019-03-19
-- optimize XPath `|` operation performance. [#33](https://github.com/antchfx/xpath/issues/33). Tips: suggest split into multiple subquery if you have a lot of `|` operations.
-
-2019-01-29
-- improvement `normalize-space` function. [#32](https://github.com/antchfx/xpath/issues/32)
-
-2018-12-07
-- supports XPath 2.0 Sequence expressions. [#30](https://github.com/antchfx/xpath/pull/30) by [@minherz](https://github.com/minherz).
\ No newline at end of file
+[^1]: XPath-2.0 expression
\ No newline at end of file
diff --git a/vendor/github.com/antchfx/xpath/build.go b/vendor/github.com/antchfx/xpath/build.go
index 58d8f31..2977bbc 100644
--- a/vendor/github.com/antchfx/xpath/build.go
+++ b/vendor/github.com/antchfx/xpath/build.go
@@ -42,8 +42,14 @@ func axisPredicate(root *axisNode) func(NodeNavigator) bool {
}
nametest := root.LocalName != "" || root.Prefix != ""
predicate := func(n NodeNavigator) bool {
- if typ == n.NodeType() || typ == allNode || typ == TextNode {
+ if typ == n.NodeType() || typ == allNode {
if nametest {
+ type namespaceURL interface {
+ NamespaceURL() string
+ }
+ if ns, ok := n.(namespaceURL); ok && root.hasNamespaceURI {
+ return root.LocalName == n.LocalName() && root.namespaceURI == ns.NamespaceURL()
+ }
if root.LocalName == n.LocalName() && root.Prefix == n.Prefix() {
return true
}
@@ -88,7 +94,10 @@ func (b *builder) processAxisNode(root *axisNode) (query, error) {
}
return v
}
- qyOutput = &descendantQuery{Input: qyGrandInput, Predicate: filter, Self: true}
+ // fix `//*[contains(@id,"food")]//*[contains(@id,"food")]`, see https://github.com/antchfx/htmlquery/issues/52
+ // Skip the current node(Self:false) for the next descendants nodes.
+ _, ok := qyGrandInput.(*contextQuery)
+ qyOutput = &descendantQuery{Input: qyGrandInput, Predicate: filter, Self: ok}
return qyOutput, nil
}
}
@@ -209,6 +218,12 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) {
if arg2, err = b.processNode(root.Args[1]); err != nil {
return nil, err
}
+ // Issue #92, testing the regular expression before.
+ if q, ok := arg2.(*constantQuery); ok {
+ if _, err = getRegexp(q.Val.(string)); err != nil {
+ return nil, fmt.Errorf("matches() got error. %v", err)
+ }
+ }
qyOutput = &functionQuery{Input: b.firstInput, Func: matchesFunc(arg1, arg2)}
case "substring":
//substring( string , start [, length] )
@@ -347,7 +362,15 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) {
},
}
case "last":
- qyOutput = &functionQuery{Input: b.firstInput, Func: lastFunc}
+ switch typ := b.firstInput.(type) {
+ case *groupQuery, *filterQuery:
+ // https://github.com/antchfx/xpath/issues/76
+ // https://github.com/antchfx/xpath/issues/78
+ qyOutput = &lastQuery{Input: typ}
+ default:
+ qyOutput = &functionQuery{Input: b.firstInput, Func: lastFunc}
+ }
+
case "position":
qyOutput = &functionQuery{Input: b.firstInput, Func: positionFunc}
case "boolean", "number", "string":
@@ -433,6 +456,19 @@ func (b *builder) processFunctionNode(root *functionNode) (query, error) {
return nil, err
}
qyOutput = &transformFunctionQuery{Input: argQuery, Func: reverseFunc}
+ case "string-join":
+ if len(root.Args) != 2 {
+ return nil, fmt.Errorf("xpath: string-join(node-sets, separator) function requires node-set and argument")
+ }
+ argQuery, err := b.processNode(root.Args[0])
+ if err != nil {
+ return nil, err
+ }
+ arg1, err := b.processNode(root.Args[1])
+ if err != nil {
+ return nil, err
+ }
+ qyOutput = &functionQuery{Input: argQuery, Func: stringJoinFunc(arg1)}
default:
return nil, fmt.Errorf("not yet support this function %s()", root.FuncName)
}
@@ -511,6 +547,7 @@ func (b *builder) processNode(root node) (q query, err error) {
b.firstInput = q
case nodeFilter:
q, err = b.processFilterNode(root.(*filterNode))
+ b.firstInput = q
case nodeFunction:
q, err = b.processFunctionNode(root.(*functionNode))
case nodeOperator:
@@ -521,12 +558,13 @@ func (b *builder) processNode(root node) (q query, err error) {
return
}
q = &groupQuery{Input: q}
+ b.firstInput = q
}
return
}
// build builds a specified XPath expressions expr.
-func build(expr string) (q query, err error) {
+func build(expr string, namespaces map[string]string) (q query, err error) {
defer func() {
if e := recover(); e != nil {
switch x := e.(type) {
@@ -539,7 +577,7 @@ func build(expr string) (q query, err error) {
}
}
}()
- root := parse(expr)
+ root := parse(expr, namespaces)
b := &builder{}
return b.processNode(root)
}
diff --git a/vendor/github.com/antchfx/xpath/func.go b/vendor/github.com/antchfx/xpath/func.go
index fd4187b..4131bfd 100644
--- a/vendor/github.com/antchfx/xpath/func.go
+++ b/vendor/github.com/antchfx/xpath/func.go
@@ -122,17 +122,19 @@ func asNumber(t iterator, o interface{}) float64 {
return typ
case string:
v, err := strconv.ParseFloat(typ, 64)
- if err != nil {
- panic(errors.New("ceiling() function argument type must be a node-set or number"))
+ if err == nil {
+ return v
}
- return v
}
- return 0
+ return math.NaN()
}
// ceilingFunc is a XPath Node Set functions ceiling(node-set).
func ceilingFunc(q query, t iterator) interface{} {
val := asNumber(t, functionArgs(q).Evaluate(t))
+ // if math.IsNaN(val) {
+ // panic(errors.New("ceiling() function argument type must be a valid number"))
+ // }
return math.Ceil(val)
}
@@ -612,3 +614,34 @@ func reverseFunc(q query, t iterator) func() NodeNavigator {
return node
}
}
+
+// string-join is a XPath Node Set functions string-join(node-set, separator).
+func stringJoinFunc(arg1 query) func(query, iterator) interface{} {
+ return func(q query, t iterator) interface{} {
+ var separator string
+ switch v := functionArgs(arg1).Evaluate(t).(type) {
+ case string:
+ separator = v
+ case query:
+ node := v.Select(t)
+ if node != nil {
+ separator = node.Value()
+ }
+ }
+
+ q = functionArgs(q)
+ test := predicate(q)
+ var parts []string
+ switch v := q.Evaluate(t).(type) {
+ case string:
+ return v
+ case query:
+ for node := v.Select(t); node != nil; node = v.Select(t) {
+ if test(node) {
+ parts = append(parts, node.Value())
+ }
+ }
+ }
+ return strings.Join(parts, separator)
+ }
+}
diff --git a/vendor/github.com/antchfx/xpath/func_go110.go b/vendor/github.com/antchfx/xpath/func_go110.go
index 6df30d3..d6ca451 100644
--- a/vendor/github.com/antchfx/xpath/func_go110.go
+++ b/vendor/github.com/antchfx/xpath/func_go110.go
@@ -11,6 +11,6 @@ func round(f float64) int {
return int(math.Round(f))
}
-func newStringBuilder() stringBuilder{
+func newStringBuilder() stringBuilder {
return &strings.Builder{}
}
diff --git a/vendor/github.com/antchfx/xpath/operator.go b/vendor/github.com/antchfx/xpath/operator.go
index 8c2f31f..eb38ac6 100644
--- a/vendor/github.com/antchfx/xpath/operator.go
+++ b/vendor/github.com/antchfx/xpath/operator.go
@@ -165,15 +165,28 @@ func cmpNodeSetString(t iterator, op string, m, n interface{}) bool {
func cmpNodeSetNodeSet(t iterator, op string, m, n interface{}) bool {
a := m.(query)
b := n.(query)
- x := a.Select(t)
- if x == nil {
- return false
- }
- y := b.Select(t)
- if y == nil {
- return false
+ for {
+ x := a.Select(t)
+ if x == nil {
+ return false
+ }
+
+ y := b.Select(t)
+ if y == nil {
+ return false
+ }
+
+ for {
+ if cmpStringStringF(op, x.Value(), y.Value()) {
+ return true
+ }
+ if y = b.Select(t); y == nil {
+ break
+ }
+ }
+ // reset
+ b.Evaluate(t)
}
- return cmpStringStringF(op, x.Value(), y.Value())
}
func cmpStringNumeric(t iterator, op string, m, n interface{}) bool {
diff --git a/vendor/github.com/antchfx/xpath/parse.go b/vendor/github.com/antchfx/xpath/parse.go
index acb0db9..cbd289a 100644
--- a/vendor/github.com/antchfx/xpath/parse.go
+++ b/vendor/github.com/antchfx/xpath/parse.go
@@ -69,8 +69,9 @@ const (
)
type parser struct {
- r *scanner
- d int
+ r *scanner
+ d int
+ namespaces map[string]string
}
// newOperatorNode returns new operator node OperatorNode.
@@ -84,8 +85,8 @@ func newOperandNode(v interface{}) node {
}
// newAxisNode returns new axis node AxisNode.
-func newAxisNode(axeTyp, localName, prefix, prop string, n node) node {
- return &axisNode{
+func newAxisNode(axeTyp, localName, prefix, prop string, n node, opts ...func(p *axisNode)) node {
+ a := axisNode{
nodeType: nodeAxis,
LocalName: localName,
Prefix: prefix,
@@ -93,6 +94,10 @@ func newAxisNode(axeTyp, localName, prefix, prop string, n node) node {
Prop: prop,
Input: n,
}
+ for _, o := range opts {
+ o(&a)
+ }
+ return &a
}
// newVariableNode returns new variable node VariableNode.
@@ -469,7 +474,16 @@ func (p *parser) parseNodeTest(n node, axeTyp string) (opnd node) {
if p.r.name == "*" {
name = ""
}
- opnd = newAxisNode(axeTyp, name, prefix, "", n)
+ opnd = newAxisNode(axeTyp, name, prefix, "", n, func(a *axisNode) {
+ if prefix != "" && p.namespaces != nil {
+ if ns, ok := p.namespaces[prefix]; ok {
+ a.hasNamespaceURI = true
+ a.namespaceURI = ns
+ } else {
+ panic(fmt.Sprintf("prefix %s not defined.", prefix))
+ }
+ }
+ })
}
case itemStar:
opnd = newAxisNode(axeTyp, "", "", "", n)
@@ -531,11 +545,11 @@ func (p *parser) parseMethod(n node) node {
}
// Parse parsing the XPath express string expr and returns a tree node.
-func parse(expr string) node {
+func parse(expr string, namespaces map[string]string) node {
r := &scanner{text: expr}
r.nextChar()
r.nextItem()
- p := &parser{r: r}
+ p := &parser{r: r, namespaces: namespaces}
return p.parseExpression(nil)
}
@@ -563,11 +577,13 @@ func (o *operatorNode) String() string {
// axisNode holds a location step.
type axisNode struct {
nodeType
- Input node
- Prop string // node-test name.[comment|text|processing-instruction|node]
- AxeType string // name of the axes.[attribute|ancestor|child|....]
- LocalName string // local part name of node.
- Prefix string // prefix name of node.
+ Input node
+ Prop string // node-test name.[comment|text|processing-instruction|node]
+ AxeType string // name of the axes.[attribute|ancestor|child|....]
+ LocalName string // local part name of node.
+ Prefix string // prefix name of node.
+ namespaceURI string // namespace URI of node
+ hasNamespaceURI bool // if namespace URI is set (can be "")
}
func (a *axisNode) String() string {
diff --git a/vendor/github.com/antchfx/xpath/query.go b/vendor/github.com/antchfx/xpath/query.go
index 6e99ce5..4e6c634 100644
--- a/vendor/github.com/antchfx/xpath/query.go
+++ b/vendor/github.com/antchfx/xpath/query.go
@@ -56,7 +56,7 @@ func (c *contextQuery) Evaluate(iterator) interface{} {
}
func (c *contextQuery) Clone() query {
- return &contextQuery{count: 0, Root: c.Root}
+ return &contextQuery{Root: c.Root}
}
// ancestorQuery is an XPath ancestor node query.(ancestor::*|ancestor-self::*)
@@ -558,8 +558,8 @@ func (f *filterQuery) do(t iterator) bool {
pt := getNodePosition(f.Input)
return int(val.Float()) == pt
default:
- if q, ok := f.Predicate.(query); ok {
- return q.Select(t) != nil
+ if f.Predicate != nil {
+ return f.Predicate.Select(t) != nil
}
}
return false
@@ -577,7 +577,7 @@ func (f *filterQuery) Select(t iterator) NodeNavigator {
node := f.Input.Select(t)
if node == nil {
- return node
+ return nil
}
node = node.Copy()
@@ -676,14 +676,12 @@ type groupQuery struct {
}
func (g *groupQuery) Select(t iterator) NodeNavigator {
- for {
- node := g.Input.Select(t)
- if node == nil {
- return nil
- }
- g.posit++
- return node.Copy()
+ node := g.Input.Select(t)
+ if node == nil {
+ return nil
}
+ g.posit++
+ return node
}
func (g *groupQuery) Evaluate(t iterator) interface{} {
@@ -691,7 +689,7 @@ func (g *groupQuery) Evaluate(t iterator) interface{} {
}
func (g *groupQuery) Clone() query {
- return &groupQuery{Input: g.Input}
+ return &groupQuery{Input: g.Input.Clone()}
}
func (g *groupQuery) position() int {
@@ -820,6 +818,8 @@ func (b *booleanQuery) Select(t iterator) NodeNavigator {
}
func (b *booleanQuery) Evaluate(t iterator) interface{} {
+ n := t.Current().Copy()
+
m := b.Left.Evaluate(t)
left := asBool(t, m)
if b.IsOr && left {
@@ -827,6 +827,8 @@ func (b *booleanQuery) Evaluate(t iterator) interface{} {
} else if !b.IsOr && !left {
return false
}
+
+ t.Current().MoveTo(n)
m = b.Right.Evaluate(t)
return asBool(t, m)
}
@@ -892,6 +894,35 @@ func (u *unionQuery) Clone() query {
return &unionQuery{Left: u.Left.Clone(), Right: u.Right.Clone()}
}
+type lastQuery struct {
+ buffer []NodeNavigator
+ counted bool
+
+ Input query
+}
+
+func (q *lastQuery) Select(t iterator) NodeNavigator {
+ return nil
+}
+
+func (q *lastQuery) Evaluate(t iterator) interface{} {
+ if !q.counted {
+ for {
+ node := q.Input.Select(t)
+ if node == nil {
+ break
+ }
+ q.buffer = append(q.buffer, node.Copy())
+ }
+ q.counted = true
+ }
+ return float64(len(q.buffer))
+}
+
+func (q *lastQuery) Clone() query {
+ return &lastQuery{Input: q.Input.Clone()}
+}
+
func getHashCode(n NodeNavigator) uint64 {
var sb bytes.Buffer
switch n.NodeType() {
diff --git a/vendor/github.com/antchfx/xpath/xpath.go b/vendor/github.com/antchfx/xpath/xpath.go
index 5f6aa89..1c0a5a2 100644
--- a/vendor/github.com/antchfx/xpath/xpath.go
+++ b/vendor/github.com/antchfx/xpath/xpath.go
@@ -141,7 +141,7 @@ func Compile(expr string) (*Expr, error) {
if expr == "" {
return nil, errors.New("expr expression is nil")
}
- qy, err := build(expr)
+ qy, err := build(expr, nil)
if err != nil {
return nil, err
}
@@ -159,3 +159,18 @@ func MustCompile(expr string) *Expr {
}
return exp
}
+
+// CompileWithNS compiles an XPath expression string, using given namespaces map.
+func CompileWithNS(expr string, namespaces map[string]string) (*Expr, error) {
+ if expr == "" {
+ return nil, errors.New("expr expression is nil")
+ }
+ qy, err := build(expr, namespaces)
+ if err != nil {
+ return nil, err
+ }
+ if qy == nil {
+ return nil, fmt.Errorf(fmt.Sprintf("undeclared variable in XPath expression: %s", expr))
+ }
+ return &Expr{s: expr, q: qy}, nil
+}
diff --git a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
index b480056..42bf32a 100644
--- a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
+++ b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/md2man.go
@@ -9,6 +9,8 @@ func Render(doc []byte) []byte {
renderer := NewRoffRenderer()
return blackfriday.Run(doc,
- []blackfriday.Option{blackfriday.WithRenderer(renderer),
- blackfriday.WithExtensions(renderer.GetExtensions())}...)
+ []blackfriday.Option{
+ blackfriday.WithRenderer(renderer),
+ blackfriday.WithExtensions(renderer.GetExtensions()),
+ }...)
}
diff --git a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
index 0668a66..4b19188 100644
--- a/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
+++ b/vendor/github.com/cpuguy83/go-md2man/v2/md2man/roff.go
@@ -1,6 +1,7 @@
package md2man
import (
+ "bytes"
"fmt"
"io"
"os"
@@ -15,7 +16,7 @@ type roffRenderer struct {
extensions blackfriday.Extensions
listCounters []int
firstHeader bool
- defineTerm bool
+ firstDD bool
listDepth int
}
@@ -34,15 +35,16 @@ const (
hruleTag = "\n.ti 0\n\\l'\\n(.lu'\n"
linkTag = "\n\\[la]"
linkCloseTag = "\\[ra]"
- codespanTag = "\\fB\\fC"
+ codespanTag = "\\fB"
codespanCloseTag = "\\fR"
- codeTag = "\n.PP\n.RS\n\n.nf\n"
- codeCloseTag = "\n.fi\n.RE\n"
+ codeTag = "\n.EX\n"
+ codeCloseTag = "\n.EE\n"
quoteTag = "\n.PP\n.RS\n"
quoteCloseTag = "\n.RE\n"
listTag = "\n.RS\n"
listCloseTag = "\n.RE\n"
- arglistTag = "\n.TP\n"
+ dtTag = "\n.TP\n"
+ dd2Tag = "\n"
tableStart = "\n.TS\nallbox;\n"
tableEnd = ".TE\n"
tableCellStart = "T{\n"
@@ -85,12 +87,11 @@ func (r *roffRenderer) RenderFooter(w io.Writer, ast *blackfriday.Node) {
// RenderNode is called for each node in a markdown document; based on the node
// type the equivalent roff output is sent to the writer
func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering bool) blackfriday.WalkStatus {
-
- var walkAction = blackfriday.GoToNext
+ walkAction := blackfriday.GoToNext
switch node.Type {
case blackfriday.Text:
- r.handleText(w, node, entering)
+ escapeSpecialChars(w, node.Literal)
case blackfriday.Softbreak:
out(w, crTag)
case blackfriday.Hardbreak:
@@ -108,9 +109,16 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering
out(w, strongCloseTag)
}
case blackfriday.Link:
- if !entering {
- out(w, linkTag+string(node.LinkData.Destination)+linkCloseTag)
+ // Don't render the link text for automatic links, because this
+ // will only duplicate the URL in the roff output.
+ // See https://daringfireball.net/projects/markdown/syntax#autolink
+ if !bytes.Equal(node.LinkData.Destination, node.FirstChild.Literal) {
+ out(w, string(node.FirstChild.Literal))
}
+ // Hyphens in a link must be escaped to avoid word-wrap in the rendered man page.
+ escapedLink := strings.ReplaceAll(string(node.LinkData.Destination), "-", "\\-")
+ out(w, linkTag+escapedLink+linkCloseTag)
+ walkAction = blackfriday.SkipChildren
case blackfriday.Image:
// ignore images
walkAction = blackfriday.SkipChildren
@@ -150,40 +158,26 @@ func (r *roffRenderer) RenderNode(w io.Writer, node *blackfriday.Node, entering
out(w, codeCloseTag)
case blackfriday.Table:
r.handleTable(w, node, entering)
- case blackfriday.TableCell:
- r.handleTableCell(w, node, entering)
case blackfriday.TableHead:
case blackfriday.TableBody:
case blackfriday.TableRow:
// no action as cell entries do all the nroff formatting
return blackfriday.GoToNext
+ case blackfriday.TableCell:
+ r.handleTableCell(w, node, entering)
+ case blackfriday.HTMLSpan:
+ // ignore other HTML tags
+ case blackfriday.HTMLBlock:
+ if bytes.HasPrefix(node.Literal, []byte("