Editace textu pomocí XPath v SVG

Step

Editace textu pomocí XPath v SVG
« kdy: 24. 01. 2019, 22:35:30 »
potrebuju upravit jeden text v svg. Zdanlive jednoduche, ale nejak jsem se zaseknul. Nedokazu formulovat XPATH pro Text1. Nejvetsi nadeje jsem daval .//*[@id="TEXT1_ID"]/tspan pripadne tomuto .//*[@id="TEXT1_ID"]/tspan/text() . Ovsem to nejak nefunguje. Pak jsem zkusil asi tak milion jinych blbosti. Pouzival jsem na to online validator: https://codebeautify.org/Xpath-Tester. Asi jsem na tom neco zle nepochopil :(




Kód: [Vybrat]
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->

<svg
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:cc="http://creativecommons.org/ns#"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:svg="http://www.w3.org/2000/svg"
   xmlns="http://www.w3.org/2000/svg"
   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
   width="210mm"
   height="297mm"
   viewBox="0 0 744.09448819 1052.3622047"
   id="svg2"
   version="1.1"
   inkscape:version="0.91 r13725"
   sodipodi:docname="testing.svg">
  <defs
     id="defs4" />
  <sodipodi:namedview
     id="base"
     pagecolor="#ffffff"
     bordercolor="#666666"
     borderopacity="1.0"
     inkscape:pageopacity="0.0"
     inkscape:pageshadow="2"
     inkscape:zoom="0.7"
     inkscape:cx="162.05782"
     inkscape:cy="758.41218"
     inkscape:document-units="px"
     inkscape:current-layer="layer1"
     showgrid="false"
     inkscape:window-width="1581"
     inkscape:window-height="1028"
     inkscape:window-x="1912"
     inkscape:window-y="22"
     inkscape:window-maximized="1" />
  <metadata
     id="metadata7">
    <rdf:RDF>
      <cc:Work
         rdf:about="">
        <dc:format>image/svg+xml</dc:format>
        <dc:type
           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
        <dc:title></dc:title>
      </cc:Work>
    </rdf:RDF>
  </metadata>
  <g
     inkscape:label="Layer 1"
     inkscape:groupmode="layer"
     id="layer1">
    <text
       xml:space="preserve"
       style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       x="155.71429"
       y="178.07649"
       id="TEXT1_ID"
       sodipodi:linespacing="125%"><tspan
         sodipodi:role="line"
         id="tspan4138"
         x="155.71429"
         y="178.07649">Text1</tspan></text>
    <text
       xml:space="preserve"
       style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
       x="155.71429"
       y="238.07649"
       id="TEXT2_ID"
       sodipodi:linespacing="125%"><tspan
         sodipodi:role="line"
         id="tspan4142"
         x="155.71429"
         y="238.07649">Text2 <tspan
   style="font-weight:bold"
   id="tspan4144">Text</tspan>3 Text4</tspan></text>
  </g>
</svg>
« Poslední změna: 24. 01. 2019, 22:42:30 od Petr Krčmář »


iiiiiii

Re:Editace textu pomocí XPath v SVG
« Odpověď #1 kdy: 24. 01. 2019, 23:07:42 »
co tohle?!

(//*[@id="TEXT1_ID"])/*/text()

Step

Re:Editace textu pomocí XPath v SVG
« Odpověď #2 kdy: 25. 01. 2019, 00:03:39 »
co tohle?!

(//*[@id="TEXT1_ID"])/*/text()

Luxusni!

Ale proc?
(//*[@id="TEXT1_ID"])/*/text() - OK
//*[@id="TEXT1_ID"]/*/text() - OK
//*[@id="TEXT1_ID"]/tspan/text() - NOK

Proc tam ten tspan nefunguje?

Kriegel

Re:Editace textu pomocí XPath v SVG
« Odpověď #3 kdy: 25. 01. 2019, 09:45:13 »
co tohle?!

(//*[@id="TEXT1_ID"])/*/text()

Luxusni!

Ale proc?
(//*[@id="TEXT1_ID"])/*/text() - OK
//*[@id="TEXT1_ID"]/*/text() - OK
//*[@id="TEXT1_ID"]/tspan/text() - NOK

Proc tam ten tspan nefunguje?

kvuli defaultnimu namespace... bud ho parser nejak pouzije (zalezi, jestli to umi), nebo ho dej docasne do pryc (smazni xmlns="http://www.w3.org/2000/svg") v <svg> a pak ho tam zase vrat...

Kit

Re:Editace textu pomocí XPath v SVG
« Odpověď #4 kdy: 25. 01. 2019, 13:23:14 »
Zkusil bych XMLStarlet:
Kód: [Vybrat]
xmlstarlet sel -t -m '//*[@id="TEXT1_ID"]/_:tspan' -v 'text()' picture.svg
Zvládne i editaci textu v elementu
Kód: [Vybrat]
xmlstarlet ed -u '//*[@id="TEXT1_ID"]/_:tspan' -v 'Nový text' picture.svg


Re:Editace textu pomocí XPath v SVG
« Odpověď #5 kdy: 25. 01. 2019, 14:07:53 »
Máte tam (správně) jmenné prostory, takže je potřeba je používat i v XPath. Pozor na to, že mapování prefixů na jmenné prostory se dělá externě (není to součást XPath výrazu, ale musíte procesoru, kterým XPath zpracováváte, to mapování předat jako parametr; a nepřebírají se do XPath ani prefixy jmenných prostorů definované v dokumentu). Pak bude fungovat //*[@id="TEXT1_ID"]/svg:tspan/text() (a musíte předat mapování svg → http://www.w3.org/2000/svg).

Druhá možnost je porovnávat QName přímo ve výrazu, ale pak nemůžete použít zkrácený zápis: //*[@id="TEXT1_ID"]/*[name() = 'tspan']/text(). Tím výrazem *[name() = 'tspan'] řeknete, že hledáte všechny elementy, které splňují podmínky v hranatých závorkách, tedy že jejich plné jméno (včetně prefixu) je tspan. Protože tspan je v defaultním jmenném prostoru, nemá žádný prefix.

Když jste použil zkrácené porovnání na QName elementu ale bez přiřazených prefixů jmenných prostorů, hledal se element tspan z prázdného jmenného prostoru, a takový v dokumentu není.

Kit

Re:Editace textu pomocí XPath v SVG
« Odpověď #6 kdy: 25. 01. 2019, 18:12:23 »
Proc tam ten tspan nefunguje?
kvuli defaultnimu namespace... bud ho parser nejak pouzije (zalezi, jestli to umi), nebo ho dej docasne do pryc (smazni xmlns="http://www.w3.org/2000/svg") v <svg> a pak ho tam zase vrat...

Takové mazání a vracení namespace je značně nesystémové a je cestou do pekel. Je třeba se naučit s namespace pracovat, jinak bude docházet k zmatkům. Zpočátku je to sice poněkud bolestivé, ale je nutné ten čas do toho investovat.

Re:Editace textu pomocí XPath v SVG
« Odpověď #7 kdy: 25. 01. 2019, 23:14:37 »
Druhá možnost je porovnávat QName přímo ve výrazu, ale pak nemůžete použít zkrácený zápis: //*[@id="TEXT1_ID"]/*[name() = 'tspan']/text(). Tím výrazem *[name() = 'tspan'] řeknete, že hledáte všechny elementy, které splňují podmínky v hranatých závorkách, tedy že jejich plné jméno (včetně prefixu) je tspan. Protože tspan je v defaultním jmenném prostoru, nemá žádný prefix.

To bude fungovat pouze za předpokladu, že svg je default namespace. Pokud chcu porovnávat jenom element name (bez namespace), je třeba použít local-name() . Pokud chcu porovnávat celé element name, je nejlepší si namespace v XPath zaregistrovat. Tohle je mix, který bude nejspíš dlouho fungovat, až se jednoho dne na jiných, ale přesto stejných datech, rozbije.

Re:Editace textu pomocí XPath v SVG
« Odpověď #8 kdy: 26. 01. 2019, 08:08:55 »
To bude fungovat pouze za předpokladu, že svg je default namespace. Pokud chcu porovnávat jenom element name (bez namespace), je třeba použít local-name() . Pokud chcu porovnávat celé element name, je nejlepší si namespace v XPath zaregistrovat. Tohle je mix, který bude nejspíš dlouho fungovat, až se jednoho dne na jiných, ale přesto stejných datech, rozbije.
Ale ten element tspan je v default namespace, podívejte se na ten dokument. local-name() nechci použít, protože to pak porovnává bez ohledu na namespace – kdyby tam byl element tspan z jiného namespace, vyhoví podmínce také.

Ano, nejlepší je namespace v XPath zaregistrovat, protože pak je XPath nezávislý na tom, jak jsou nadefinované prefixy v konkrétním dokumentu.