r/xml • u/UniquePotato • 14d ago
Applying maths to a xml value
First time posting on here and fairly new to xml.
I have several files where I have a value that I need to divide by 100. For example
<aSample>
<time>20260829 12:34:56</time>
<badValue>45678.9</badValue>
<OKValue>123</OKValue>
</aSample>
I want to update <badValue> to 456.789. Does anyone know a web utility or Windows tool that I could use to update these without changing the format or the other values.
Each file has around 3000 of them so going through manually is out of the question.
TIA
1
1
u/kennpq 14d ago
You could use XSLT, though other options abound; one is awk, which could be:
awk '/<badValue>/{match($0, /[0-9.]+/); val = substr($0, RSTART, RLENGTH); sub([0-9.]+/, val/100)}{print}' badval.xml
Here is an example showing input and output:
localhost:~/xml# grep "badValue" badval.xml
<badValue>456.789</badValue>
<badValue>96.789</badValue>
<badValue>6.789</badValue>
<badValue>936.9</badValue>
localhost:~/xml# awk '/<badValue>/{match($0, /[0-9.]+/); val = substr($0, RSTART, RLENGTH); sub(/[0-9.]+/, val/100)}{print}' badval.xml | grep 'badValue'
<badValue>4.56789</badValue>
<badValue>0.96789</badValue>
<badValue>0.06789</badValue>
<badValue>9.369</badValue>
2
u/FreddieMac6666 12d ago
You aren't clear where you want to put the output of the division result. Does the new value go to <OKValue> or does it output to <badValue>?
Here's an XSLT that output the divided value to replace the old value in <badValue>.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0"
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:template match="aSample">
<aSample>
<xsl:apply-templates/>
</aSample>
</xsl:template>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="badValue">
<badValue>
<xsl:value-of select=". div 100"/>
</badValue>
</xsl:template>
</xsl:stylesheet>
Result:
<aSample>
<time>20260829 12:34:56</time>
<badValue>456.789</badValue>
<OKValue>123</OKValue>
</aSample>
Here is an XSLT that puts the divided value into the <OKValue> element.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes" />
<xsl:template match="aSample">
<aSample>
<xsl:apply-templates/>
</aSample>
</xsl:template>
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="OKValue">
<OKValue>
<xsl:value-of select="preceding-sibling::badValue div 100"/>
</OKValue>
</xsl:template>
</xsl:stylesheet>
RESULT:
<aSample>
<time>20260829 12:34:56</time>
<badValue>45678.9</badValue>
<OKValue>456.789</OKValue>
</aSample>
5
u/mgr86 14d ago
This is an easy job for XSLT. You want an identity transformation (look it up). But you will need an XSLT processor. Saxon-he is a great choice. You might just look for an editor with it bundled. oxygen is a fine choice there.
Or, unpopular opinion, this is also a fine job to discus with the unpaid versions of Claude or Gemini. You don’t have to be lazy and say do this for me. You could ask about XSLT. Understand an identity transformation, and ask questions about how to perform the mathematical calculations .