强制十进制SimpleType中的空十进制占位符

时间:2014-10-10 13:28:07

标签: sql sql-server xml xsd formatting

我有一个产生货币金额的XML,这通常是货币转换的结果,因此需要以很高的准确度显示(在本例中为4dp)。我发现虽然我可以使用这样列出的数字生成XML,但只要我在XML上强制执行一个模式,所有的"不必要的"删除0位数。虽然我可以从计算机的角度理解这一点,但我们需要向我们的客户准确显示我们的所有数字的数字准确度,无论每个数字的值如何。为了他们的理解,如果我们保持一致,我们总是在这些数字上显示正好4个小数位,那就更清楚了。下面是一个示例,您可以运行以查看我的意思(比较之前和之后的结果):

/*
This script will create a schema collection, use it and drop it, so there is minimal chance of mess left behind
*/
DECLARE @XSD XML

SET @XSD = CONVERT(XML,
'<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="xs3p.xsl"?>
<xs:schema id="MyData"
  targetNamespace="http://tempuri.org/MyData.xsd"
  elementFormDefault="qualified"
  xmlns="http://tempuri.org/MyData.xsd"
  xmlns:mstns="http://tempuri.org/MyData.xsd"
  xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:simpleType name="Money">
    <xs:restriction base="xs:decimal">
      <xs:totalDigits value="14" />
      <xs:fractionDigits value="4" />
    </xs:restriction>
  </xs:simpleType>
  <xs:element name="Root">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Amount" type="Money" minOccurs="1" maxOccurs="unbounded">
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>')

-- Clean if there is owt to clean
IF EXISTS (SELECT * FROM sys.xml_schema_collections WHERE name = 'TestMoney')
    DROP XML SCHEMA COLLECTION TestMoney

-- use our xml bit above to make a new schema collection
CREATE XML SCHEMA COLLECTION TestMoney AS @XSD
GO

-- we'll create our xml untyped first, so we can check it before we change it
DECLARE @Untyped_XML XML
-- this is the real test, with the schema enforced
DECLARE @XML XML(TestMoney)

-- build some test data
SET @Untyped_XML =
'<?xml version ="1.0"?>
<Root xmlns ="http://tempuri.org/MyData.xsd">
  <Amount>1.0000</Amount>
  <Amount>0.1234</Amount>
</Root>'

-- try to apply the schema collection to our xml, and show something useful whatever happens.
BEGIN TRY
    SET @XML = @Untyped_XML
    SELECT @Untyped_XML AS Before, @XML AS [After]
END TRY
BEGIN CATCH
    SELECT
         ERROR_MESSAGE()    AS Problem
        ,@Untyped_XML       AS FailedXML
END CATCH
GO
-- We don't really want this schema; it was just a test
DROP XML SCHEMA COLLECTION TestMoney

有没有办法强制数字以完全准确的方式显示?

1 个答案:

答案 0 :(得分:0)

好的,所以似乎没有简单的方法可以做到这一点 - 因此,我的解决方案是通过仅尝试来验证xml来回避问题。然后,如果验证没有给出错误,我推断出untyped_XML可以通过键入成功并将其返回为正确。这有一个缺点,我将不得不继续使用无类型的xml,但它确实意味着至少它看起来完美的模式的度量。为此,我用这个替换了问题中的TRY / CATCH:

-- try to apply the schema collection to our xml, and show something useful whatever happens.
BEGIN TRY
    SELECT @XML = @UNTYPED_XML
END TRY
BEGIN CATCH
    SELECT @SchemaError =  ERROR_MESSAGE()
END CATCH

-- If there was no error, then it is because the schema validated correctly, so show the original file.
IF @SchemaError IS NULL
    SELECT @Untyped_XML
-- If there was an error, then display it, with the bad xml
ELSE
    SELECT @SchemaError AS 'ErrorEncountered', @Untyped_XML AS FailedXML
GO

这是不能令人满意的,但是它解决了我想的问题,并且在生成之后没有将样式表应用到xml(在SSIS中,可能是使用XML任务),这似乎是最好的。