How to find and replace with a certain multiple of different values in a document?



  • Untitled.png

    There are multiple instances of values like “<Damage>” I’d like to slash every value by 50%, is it possible using Notepad++?



  • @Intoxicated-Wombat said in How to find and replace with a certain multiple of different values in a document?:

    instances of values like “<Damage>”

    You can’t do calculations with regular expressions. What could be used is Pythonscript (one amongst many supported programming languages) to do the calculations and replacements. Some forum members here use those languages and might provide some code.

    However you say “like” and “slash every value by 50%”. You will need to be specific. Which <tags> need their value changed?

    Terry



  • @Intoxicated-Wombat

    Since you wrote

    … multiple instances of values like “<Damage>”

    I guess you want to change the values of more tags than only the Damage tags. Normally I would recommend to use the XML Tools plugin and its XSL transformation feature. But I became aware of a bug in the most recent version of this plugin (already filed an issue). Thus, I would like to suggest the following solutions:

    1. Use the XML Tools plugin and the XSL file provided below, edit it according to the suggestions and call the XSL transformation feature multiple times, once for every tag you want to change.
    2. Use MSXSL.exe (you can download it from >>> here <<<) and write a batch script to call it multiple times, once for every tag you want to change. I provided a similar solution in this comment. This is the preferred solution for changing lots of tags.

    The XSL file:

    <?xml version="1.0" encoding="utf-8"?>
    
    <xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:output
          method="xml"
          indent="yes"
          omit-xml-declaration="no"
          encoding="utf-8"
        />
    
        <xsl:param name="tagName"/>
        
        <xsl:template match="@*|node()">
            <xsl:choose>
                <xsl:when test="name()=$tagName">
                    <xsl:copy>
                        <xsl:copy-of select="@*"/>
                        <xsl:value-of select="format-number(text() * 0.5, '0.000000')"/>
                        <xsl:copy-of select="*"/>
                    </xsl:copy>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:copy>
                        <xsl:apply-templates select="@*|node()"/>
                    </xsl:copy>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:template>
    
    </xsl:transform>
    

    If you want to use solution 1 from above, you have to edit line 16 and change it to something like that (replace xxx with the name of the XML tag you want to change):

    <xsl:when test="name()='xxx'">
    

    If you want to use solution 2, you have to call MSXSL.exe as follows (replace xxx with the name of the XML tag you want to change):

    msxsl.exe "<path-to-XML-file>" "<path-to-XSL-file>" -o "<path-to-output-file>" tagName='xxx'
    


  • Below is a Python Script, which will change ALL occurrences of Damage to 50% of their value,:

    import xml.etree.ElementTree as ET
    
    def is_float(value):
        try:
            float(value)
            return True
        except:
            return False
    
    root = ET.XML(editor.getText())
    
    for damage in root.findall(".//Damage"):
        if damage is not None and damage.text is not None and len(damage.text) > 0 and is_float(damage.text):
            value = float(damage.text.strip()) * 0.5
            damage.text  = "{:.6f}".format(value)
    
    editor.setText(ET.tostring(root))
    

Log in to reply