如何将十进制值转换为度、分和秒 (DMS)
How to convert decimal value in Degree, Minute and Second(DMS)
这里我们尝试将十进制值转换为度、分、秒。有什么可以帮助我们的吗?请看下面的例子:
注意:我们这里遵循的规则是:
输入XML:
<?xml version="1.0" encoding="UTF-8"?>
<POSITION>
<LATITUDE>36.812600015S</LATITUDE>
<LONGITUDE>175.430266714E</LONGITUDE>
</POSITION>
预期输出:
<?xml version="1.0" encoding="UTF-8"?>
<POSITION>
<LATITUDE>36° 48' 76''S</LATITUDE>
<LONGITUDE>175° 25' 82''E</LONGITUDE>
</POSITION>
XSLT 代码:
<?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:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="LATITUDE">
<LATITUDE>
<xsl:variable name="LATITUDE" select="."/>
<xsl:variable name="DEGREE" select="substring-before($LATITUDE,'.')"/>
<xsl:variable name="MINUTE" select="substring-before(substring-after($LATITUDE,$DEGREE),'S')"/>
<xsl:value-of select="."/>
</LATITUDE>
</xsl:template>
<xsl:template match="LONGITUDE">
<LONGITUDE>
<xsl:variable name="LONGITUDE" select="."/>
<xsl:variable name="DEGREE" select="substring-before($LONGITUDE,'.')"/>
<xsl:variable name="MINUTE" select="substring-before(substring-after($LONGITUDE,$DEGREE),'E')"/>
<xsl:value-of select="."/>
</LONGITUDE>
</xsl:template>
</xsl:stylesheet>
参考 Link : https://xsltfiddle.liberty-development.net/nb9PtDy/1
由于您使用的是 XSLT 2.0,因此您可以使用 xsl:analyze-string 来获取片段以使用正则表达式进行处理。
您必须将一些字符串转换为 xs:decimal,但这不会太复杂...
XML 输入(从屏幕截图添加示例)
<POSITION>
<EXAMPLE>156.742</EXAMPLE>
<LATITUDE>36.812600015S</LATITUDE>
<LONGITUDE>175.430266714E</LONGITUDE>
</POSITION>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:so="urn:SO"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:function name="so:convert">
<xsl:param name="degrees"/>
<xsl:analyze-string select="normalize-space($degrees)" regex="^(\d+)(\.\d+)([NSEW]?)$">
<xsl:matching-substring>
<xsl:variable name="minsec" select="xs:decimal(regex-group(2)) * 60"/>
<xsl:value-of select="concat(regex-group(1),'° ',
substring-before(string($minsec),'.'),''' ',
round(xs:decimal(concat('.',substring-after(string($minsec),'.'))) * 60),'"',
regex-group(3))"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="$degrees"/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:template match="LATITUDE|LONGITUDE|EXAMPLE">
<xsl:copy>
<xsl:value-of select="so:convert(.)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出
<POSITION>
<EXAMPLE>156° 44' 31"</EXAMPLE>
<LATITUDE>36° 48' 45"S</LATITUDE>
<LONGITUDE>175° 25' 49"E</LONGITUDE>
</POSITION>
已更新 fiddle:https://xsltfiddle.liberty-development.net/nb9PtDy/2
我会采取完全不同的方法:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="LATITUDE | LONGITUDE">
<xsl:variable name="dec" select="xs:decimal(replace(., '[NSWE]', ''))" />
<xsl:variable name="dur" select="$dec * xs:dayTimeDuration('PT1H')" />
<xsl:copy>
<!-- degrees -->
<xsl:value-of select="24 * days-from-duration($dur) + hours-from-duration($dur)"/>
<xsl:text>° </xsl:text>
<!-- minutes -->
<xsl:value-of select="minutes-from-duration($dur)"/>
<xsl:text>' </xsl:text>
<!-- seconds -->
<xsl:value-of select="round(seconds-from-duration($dur))"/>
<xsl:text>"</xsl:text>
<!-- hemisphere -->
<xsl:value-of select="replace(., '[^NSWE]', '')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
这里我们尝试将十进制值转换为度、分、秒。有什么可以帮助我们的吗?请看下面的例子:
注意:我们这里遵循的规则是:
输入XML:
<?xml version="1.0" encoding="UTF-8"?>
<POSITION>
<LATITUDE>36.812600015S</LATITUDE>
<LONGITUDE>175.430266714E</LONGITUDE>
</POSITION>
预期输出:
<?xml version="1.0" encoding="UTF-8"?>
<POSITION>
<LATITUDE>36° 48' 76''S</LATITUDE>
<LONGITUDE>175° 25' 82''E</LONGITUDE>
</POSITION>
XSLT 代码:
<?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:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="LATITUDE">
<LATITUDE>
<xsl:variable name="LATITUDE" select="."/>
<xsl:variable name="DEGREE" select="substring-before($LATITUDE,'.')"/>
<xsl:variable name="MINUTE" select="substring-before(substring-after($LATITUDE,$DEGREE),'S')"/>
<xsl:value-of select="."/>
</LATITUDE>
</xsl:template>
<xsl:template match="LONGITUDE">
<LONGITUDE>
<xsl:variable name="LONGITUDE" select="."/>
<xsl:variable name="DEGREE" select="substring-before($LONGITUDE,'.')"/>
<xsl:variable name="MINUTE" select="substring-before(substring-after($LONGITUDE,$DEGREE),'E')"/>
<xsl:value-of select="."/>
</LONGITUDE>
</xsl:template>
</xsl:stylesheet>
参考 Link : https://xsltfiddle.liberty-development.net/nb9PtDy/1
由于您使用的是 XSLT 2.0,因此您可以使用 xsl:analyze-string 来获取片段以使用正则表达式进行处理。
您必须将一些字符串转换为 xs:decimal,但这不会太复杂...
XML 输入(从屏幕截图添加示例)
<POSITION>
<EXAMPLE>156.742</EXAMPLE>
<LATITUDE>36.812600015S</LATITUDE>
<LONGITUDE>175.430266714E</LONGITUDE>
</POSITION>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:so="urn:SO"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:function name="so:convert">
<xsl:param name="degrees"/>
<xsl:analyze-string select="normalize-space($degrees)" regex="^(\d+)(\.\d+)([NSEW]?)$">
<xsl:matching-substring>
<xsl:variable name="minsec" select="xs:decimal(regex-group(2)) * 60"/>
<xsl:value-of select="concat(regex-group(1),'° ',
substring-before(string($minsec),'.'),''' ',
round(xs:decimal(concat('.',substring-after(string($minsec),'.'))) * 60),'"',
regex-group(3))"/>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select="$degrees"/>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:function>
<xsl:template match="LATITUDE|LONGITUDE|EXAMPLE">
<xsl:copy>
<xsl:value-of select="so:convert(.)"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出
<POSITION>
<EXAMPLE>156° 44' 31"</EXAMPLE>
<LATITUDE>36° 48' 45"S</LATITUDE>
<LONGITUDE>175° 25' 49"E</LONGITUDE>
</POSITION>
已更新 fiddle:https://xsltfiddle.liberty-development.net/nb9PtDy/2
我会采取完全不同的方法:
XSLT 2.0
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="LATITUDE | LONGITUDE">
<xsl:variable name="dec" select="xs:decimal(replace(., '[NSWE]', ''))" />
<xsl:variable name="dur" select="$dec * xs:dayTimeDuration('PT1H')" />
<xsl:copy>
<!-- degrees -->
<xsl:value-of select="24 * days-from-duration($dur) + hours-from-duration($dur)"/>
<xsl:text>° </xsl:text>
<!-- minutes -->
<xsl:value-of select="minutes-from-duration($dur)"/>
<xsl:text>' </xsl:text>
<!-- seconds -->
<xsl:value-of select="round(seconds-from-duration($dur))"/>
<xsl:text>"</xsl:text>
<!-- hemisphere -->
<xsl:value-of select="replace(., '[^NSWE]', '')"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>