2

我需要将源架构定义的所有 Float 和 Double 数据类型转换为十进制数据类型。

我们有一个现有的 XSLT,它从第三方获取 XML 文档并将其转换为 XML 结构,然后我们可以将其传递到我们的 4GL DB 应用程序中。原生 4GL 接口的好处在于它可以将入站 XML 转换为原生 Dataset 结构。不足之处在于它将 Float 和 Double 数据类型映射到字符数据类型。

在 XSLT 中是否有一种方法可以识别 Float/Double 数据类型的元素并将其转换为小数。我在想这可能是主要的 XSLT 步骤,然后将输出传递到主要的 XSLT。

示例模式在:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="ttPTManifest">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="JobCode"/>
                <xs:element ref="EstimateHours"/>
                <xs:element ref="ActualHours"/>
                <xs:element ref="Density"/>
                <xs:element ref="NettLitres"/>
                <xs:element ref="QuitOutLitres"/>
                <xs:element ref="QuitInLitres"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="QuitOutLitres" type="xs:double"/>
    <xs:element name="QuitInLitres" type="xs:float"/>
    <xs:element name="PTManifestSonicIn">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="ttPTManifest"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="JobCode" type="xs:string"/>
    <xs:element name="NettLitres" type="xs:double"/>
    <xs:element name="EstimateHours" type="xs:float"/>
    <xs:element name="Density" type="xs:decimal"/>
    <xs:element name="ActualHours" type="xs:float"/>
</xs:schema>

示例 XML 数据在:

<?xml version="1.0"?>
<PTManifestSonicIn xsi:noNamespaceSchemaLocation="SampleIn.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <ttPTManifest>
        <JobCode>000123</JobCode>
        <EstimateHours>3.14159E3</EstimateHours>
        <ActualHours>3.14159E3</ActualHours>
        <Density>123.456</Density>
        <NettLitres>3.14159265358979E3</NettLitres>
        <QuitOutLitres>3.14159265358979E3</QuitOutLitres>
        <QuitInLitres>3.14159E3</QuitInLitres>
    </ttPTManifest>
</PTManifestSonicIn>

所需的架构输出:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xs:element name="ttPTManifest">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="JobCode"/>
                <xs:element ref="EstimateHours"/>
                <xs:element ref="ActualHours"/>
                <xs:element ref="Density"/>
                <xs:element ref="NettLitres"/>
                <xs:element ref="QuitOutLitres"/>
                <xs:element ref="QuitInLitres"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="QuitOutLitres" type="xs:decimal"/>
    <xs:element name="QuitInLitres" type="xs:decimal"/>
    <xs:element name="PTManifestSonicIn">
        <xs:complexType>
            <xs:sequence>
                <xs:element ref="ttPTManifest"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
    <xs:element name="JobCode" type="xs:string"/>
    <xs:element name="NettLitres" type="xs:decimal"/>
    <xs:element name="EstimateHours" type="xs:decimal"/>
    <xs:element name="Density" type="xs:decimal"/>
    <xs:element name="ActualHours" type="xs:decimal"/>
</xs:schema>

所需的 XML 数据输出:

<?xml version="1.0"?>
<PTManifestSonicIn xsi:noNamespaceSchemaLocation="SampleOut.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <ttPTManifest>
        <JobCode>000123</JobCode>
        <EstimateHours>3141.59</EstimateHours>
        <ActualHours>3141.59</ActualHours>
        <Density>123.456</Density>
        <NettLitres>3141.59265358979</NettLitres>
        <QuitOutLitres>3141.59265358979</QuitOutLitres>
        <QuitInLitres>3141.59</QuitInLitres>
    </ttPTManifest>
</PTManifestSonicIn>
4

2 回答 2

1

为了转换 XML 数据,您可以使用以下样式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    version="2.0">
    <xsl:output indent="yes"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template 
           match="*
                  [local-name(.)=document(/*/@xsi:noNamespaceSchemaLocation)/*/xs:element[@type=('xs:double', 'xs:float')]/@name]
                  [. castable as xs:double or . castable as xs:float]">
        <xsl:copy>
            <xsl:value-of select="number(.)"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

您可以使用以下样式表转换 Schema:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    version="2.0">
    <xsl:output indent="yes"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@type[.=('xs:double', 'xs:float')]">
        <xsl:attribute name="type" select="'xs:decimal'"/>
    </xsl:template>

</xsl:stylesheet>
于 2012-09-19T00:14:33.697 回答
1

如果您可以使用 XSL v2,请使用 Mads 的答案。如果您坚持使用 v1,这可以进行 XSD 转换:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="xs:element[@type='xs:double' or @type='xs:float']">
        <xsl:copy>
            <xsl:attribute name="name"><xsl:value-of select="@name"/></xsl:attribute>
            <xsl:attribute name="type">xs:decimal</xsl:attribute>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

这可用于转换 XML:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    version="1.0">
    <xsl:output indent="yes"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template 
          match="*
                  [local-name(.)=document(/*/@xsi:noNamespaceSchemaLocation)/*/xs:element[@type='xs:double' or @type='xs:float']/@name]
                  [number(.)=number(.)]">
        <xsl:copy>
            <xsl:value-of select="number(.)"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>
于 2012-09-19T09:01:52.473 回答