質問

I am validating a XML-document to verify a total sum like this (Sorry for the standard example):

<book>
    <name>Book 1</name>
    <price>25.30</price>
</book>
<book>
    <name>Book 2</name>
    <price>20.77</price>
</book>
<sum>46.07</sum>

I load the xml and validation schema, and generates a xml as output. This output contains info about which errors occured:

var xml = new XmlDocument();
xml.Load(@"c:\test.xml")

var myXslTrans = new XslCompiledTransform();
myXslTrans.Load(@"c:\ValidationSchema.xml";);
var xmlDocOut = new XmlDocument();

    using (XmlWriter xmlWriter = xmlDocOut.CreateNavigator().AppendChild())
    {
        myXslTrans.Transform(xml, null, xmlWriter);
    }

For some reason my validation always fails when I have decimal values.

I have tried loading both documents with

CultureInfo.InvariantCulture

I have also changed the whole thread to run with this culture. Can this have anything to do with encoding?


EDIT:

To clarify this even further:

The validation succeeds if I run it early in the code, but after some giant server jobs are finished, it seems some global setting of some kind alters some culture, encoding or something, but i cannot find out where the problem arises or why.

I am verifying an electronic invoice towards this schema: http://vefa.difi.no/formatvalidering/resources/validation-xslt/NORWAY-UBL-T10.xsl

Here is my test-invoice:

<?xml version="1.0" encoding="utf-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2" xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2" xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" xmlns:ccts="urn:un:unece:uncefact:documentation:2" xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2" xmlns:qdt="urn:oasis:names:specification:ubl:schema:xsd:QualifiedDatatypes-2" xmlns:udt="urn:un:unece:uncefact:data:specification:UnqualifiedDataTypesSchemaModule:2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2 UBL-Invoice-2.0.xsd">
  <cbc:UBLVersionID>2.0</cbc:UBLVersionID>
  <cbc:CustomizationID>urn:www.cenbii.eu:transaction:biicoretrdm010:ver1.0</cbc:CustomizationID>
  <cbc:ProfileID>urn:www.cenbii.eu:profile:bii05:ver1.0</cbc:ProfileID>
  <cbc:ID>30300109</cbc:ID>
  <cbc:IssueDate>2012-05-09</cbc:IssueDate>
  <cbc:InvoiceTypeCode listID="UN/ECE 1001 Subset" listAgencyID="6">380</cbc:InvoiceTypeCode>
  <cbc:Note languageID="no">Invoice</cbc:Note>
  <cbc:DocumentCurrencyCode listID="ISO 4217" listAgencyID="5">NOK</cbc:DocumentCurrencyCode>
  <cbc:AccountingCost>
  </cbc:AccountingCost>
  <cac:OrderReference>
    <cbc:ID>1234</cbc:ID>
  </cac:OrderReference>
  <cac:ContractDocumentReference>
    <cbc:ID>
    </cbc:ID>
  </cac:ContractDocumentReference>
  <cac:AdditionalDocumentReference>
    <cbc:ID>1 - 30300109 Faktura</cbc:ID>
    <cbc:DocumentType>Commercial invoice</cbc:DocumentType>
    <cac:Attachment>
      <cbc:EmbeddedDocumentBinaryObject mimeCode="application/pdf">123123123123</cbc:EmbeddedDocumentBinaryObject>
    </cac:Attachment>
  </cac:AdditionalDocumentReference>
  <cac:AccountingSupplierParty>
    <cac:Party>
      <cac:PartyName>
        <cbc:Name>Demo</cbc:Name>
      </cac:PartyName>
      <cac:PostalAddress>
        <cbc:StreetName>Postbox 3</cbc:StreetName>
        <cbc:CityName>OSLO</cbc:CityName>
        <cbc:PostalZone>0631</cbc:PostalZone>
        <cac:Country>
          <cbc:IdentificationCode listID="ISO 3166" listAgencyID="5">NO</cbc:IdentificationCode>
        </cac:Country>
      </cac:PostalAddress>
      <cac:PartyTaxScheme>
        <cbc:CompanyID>NO910667831MVA</cbc:CompanyID>
        <cac:TaxScheme>
          <cbc:ID>VAT</cbc:ID>
        </cac:TaxScheme>
      </cac:PartyTaxScheme>
      <cac:PartyLegalEntity>
        <cbc:CompanyID schemeID="CVR" schemeAgencyID="ZZZ">910667831</cbc:CompanyID>
      </cac:PartyLegalEntity>
      <cac:Contact>
        <cbc:ID>Per</cbc:ID>
      </cac:Contact>
    </cac:Party>
  </cac:AccountingSupplierParty>
  <cac:AccountingCustomerParty>
    <cac:Party>
      <cac:PartyIdentification>
        <cbc:ID>2072</cbc:ID>
      </cac:PartyIdentification>
      <cac:PartyName>
        <cbc:Name>Wenzel</cbc:Name>
      </cac:PartyName>
      <cac:PostalAddress>
        <cbc:StreetName>Road 4</cbc:StreetName>
        <cbc:CityName>OSLO</cbc:CityName>
        <cbc:PostalZone>0404</cbc:PostalZone>
        <cac:Country>
          <cbc:IdentificationCode listID="ISO 3166" listAgencyID="5">NO</cbc:IdentificationCode>
        </cac:Country>
      </cac:PostalAddress>
      <cac:PartyLegalEntity>
        <cbc:CompanyID schemeAgencyID="ZZZ" schemeID="ZZZ">986532951</cbc:CompanyID>
      </cac:PartyLegalEntity>
      <cac:Contact>
        <cbc:ID>ww</cbc:ID>
      </cac:Contact>
    </cac:Party>
  </cac:AccountingCustomerParty>
  <cac:Delivery>
    <cbc:ActualDeliveryDate>2012-05-09</cbc:ActualDeliveryDate>
    <cac:DeliveryLocation>
      <cac:Address>
        <cbc:StreetName>Road 123</cbc:StreetName>
        <cbc:CityName>OSLO</cbc:CityName>
        <cbc:PostalZone>0404</cbc:PostalZone>
        <cac:Country>
          <cbc:IdentificationCode>NO</cbc:IdentificationCode>
        </cac:Country>
      </cac:Address>
    </cac:DeliveryLocation>
  </cac:Delivery>
  <cac:PaymentMeans>
    <cbc:PaymentMeansCode listID="UN/ECE 4461">31</cbc:PaymentMeansCode>
    <cbc:PaymentDueDate>2012-06-08</cbc:PaymentDueDate>
    <cbc:PaymentID>1020720303001099</cbc:PaymentID>
    <cac:PayeeFinancialAccount>
      <cbc:ID schemeID="BBAN">50841051308</cbc:ID>
    </cac:PayeeFinancialAccount>
  </cac:PaymentMeans>
  <cac:AllowanceCharge>
    <cbc:ChargeIndicator>false</cbc:ChargeIndicator>
    <cbc:AllowanceChargeReason>rebate</cbc:AllowanceChargeReason>
    <cbc:Amount currencyID="NOK">4664.21</cbc:Amount>
    <cac:TaxCategory>
      <cbc:ID schemeID="UN/ECE 5305" schemeAgencyID="6">S</cbc:ID>
      <cbc:Percent>25</cbc:Percent>
      <cac:TaxScheme>
        <cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">VAT</cbc:ID>
      </cac:TaxScheme>
    </cac:TaxCategory>
  </cac:AllowanceCharge>
  <cac:AllowanceCharge>
    <cbc:ChargeIndicator>true</cbc:ChargeIndicator>
    <cbc:AllowanceChargeReason>delivery</cbc:AllowanceChargeReason>
    <cbc:Amount currencyID="NOK">2938.45</cbc:Amount>
    <cac:TaxCategory>
      <cbc:ID schemeID="UN/ECE 5305" schemeAgencyID="6">S</cbc:ID>
      <cbc:Percent>24.000</cbc:Percent>
      <cac:TaxScheme>
        <cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">VAT</cbc:ID>
      </cac:TaxScheme>
    </cac:TaxCategory>
  </cac:AllowanceCharge>
  <cac:TaxTotal>
    <cbc:TaxAmount currencyID="NOK">11229.08</cbc:TaxAmount>
    <cac:TaxSubtotal>
      <cbc:TaxableAmount currencyID="NOK">44916.30</cbc:TaxableAmount>
      <cbc:TaxAmount currencyID="NOK">11229.08</cbc:TaxAmount>
      <cac:TaxCategory>
        <cbc:ID schemeID="UN/ECE 5305" schemeAgencyID="6">S</cbc:ID>
        <cbc:Percent>25</cbc:Percent>
        <cac:TaxScheme>
          <cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">VAT</cbc:ID>
        </cac:TaxScheme>
      </cac:TaxCategory>
    </cac:TaxSubtotal>
  </cac:TaxTotal>
  <cac:LegalMonetaryTotal>
    <cbc:LineExtensionAmount currencyID="NOK">46642.06</cbc:LineExtensionAmount>
    <cbc:TaxExclusiveAmount currencyID="NOK">44916.30</cbc:TaxExclusiveAmount>
    <cbc:TaxInclusiveAmount currencyID="NOK">56145.38</cbc:TaxInclusiveAmount>
    <cbc:AllowanceTotalAmount currencyID="NOK">4664.21</cbc:AllowanceTotalAmount>
    <cbc:ChargeTotalAmount currencyID="NOK">2938.45</cbc:ChargeTotalAmount>
    <!--<cbc:PrepaidAmount currencyID=""></cbc:PrepaidAmount>
    <cbc:PayableRoundingAmount currencyID=""></cbc:PayableRoundingAmount>-->
    <cbc:PayableAmount currencyID="NOK">56145.38</cbc:PayableAmount>
  </cac:LegalMonetaryTotal>
  <cac:InvoiceLine>
    <cbc:ID>1</cbc:ID>
    <cbc:InvoicedQuantity unitCode="EA">1.00</cbc:InvoicedQuantity>
    <cbc:LineExtensionAmount currencyID="NOK">12000.00</cbc:LineExtensionAmount>
    <cac:OrderLineReference>
      <cbc:LineID>1</cbc:LineID>
    </cac:OrderLineReference>
    <cac:TaxTotal>
      <cbc:TaxAmount currencyID="NOK">2700.00</cbc:TaxAmount>
    </cac:TaxTotal>
    <cac:Item>
      <cbc:Name>Skrivebord</cbc:Name>
      <cac:SellersItemIdentification>
        <cbc:ID>13000</cbc:ID>
      </cac:SellersItemIdentification>
      <cac:ClassifiedTaxCategory>
        <cbc:ID schemeID="UN/ECE 5305" schemeAgencyID="6">S</cbc:ID>
        <cbc:Percent>25.00</cbc:Percent>
        <cac:TaxScheme>
          <cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">VAT</cbc:ID>
        </cac:TaxScheme>
      </cac:ClassifiedTaxCategory>
    </cac:Item>
    <cac:Price>
      <cbc:PriceAmount currencyID="NOK">12000</cbc:PriceAmount>
    </cac:Price>
  </cac:InvoiceLine>
  <cac:InvoiceLine>
    <cbc:ID>2</cbc:ID>
    <cbc:InvoicedQuantity unitCode="EA">2.00</cbc:InvoicedQuantity>
    <cbc:LineExtensionAmount currencyID="NOK">30000.00</cbc:LineExtensionAmount>
    <cac:OrderLineReference>
      <cbc:LineID>2</cbc:LineID>
    </cac:OrderLineReference>
    <cac:TaxTotal>
      <cbc:TaxAmount currencyID="NOK">6750.00</cbc:TaxAmount>
    </cac:TaxTotal>
    <cac:Item>
      <cbc:Name>Kontorstol</cbc:Name>
      <cac:SellersItemIdentification>
        <cbc:ID>13002</cbc:ID>
      </cac:SellersItemIdentification>
      <cac:ClassifiedTaxCategory>
        <cbc:ID schemeID="UN/ECE 5305" schemeAgencyID="6">S</cbc:ID>
        <cbc:Percent>25.00</cbc:Percent>
        <cac:TaxScheme>
          <cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">VAT</cbc:ID>
        </cac:TaxScheme>
      </cac:ClassifiedTaxCategory>
    </cac:Item>
    <cac:Price>
      <cbc:PriceAmount currencyID="NOK">15000</cbc:PriceAmount>
    </cac:Price>
  </cac:InvoiceLine>
  <cac:InvoiceLine>
    <cbc:ID>3</cbc:ID>
    <cbc:InvoicedQuantity unitCode="MTR">14.50</cbc:InvoicedQuantity>
    <cbc:LineExtensionAmount currencyID="NOK">3465.50</cbc:LineExtensionAmount>
    <cac:OrderLineReference>
      <cbc:LineID>3</cbc:LineID>
    </cac:OrderLineReference>
    <cac:TaxTotal>
      <cbc:TaxAmount currencyID="NOK">779.74</cbc:TaxAmount>
    </cac:TaxTotal>
    <cac:Item>
      <cbc:Name>Persienne</cbc:Name>
      <cac:SellersItemIdentification>
        <cbc:ID>13006</cbc:ID>
      </cac:SellersItemIdentification>
      <cac:ClassifiedTaxCategory>
        <cbc:ID schemeID="UN/ECE 5305" schemeAgencyID="6">S</cbc:ID>
        <cbc:Percent>25.00</cbc:Percent>
        <cac:TaxScheme>
          <cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">VAT</cbc:ID>
        </cac:TaxScheme>
      </cac:ClassifiedTaxCategory>
    </cac:Item>
    <cac:Price>
      <cbc:PriceAmount currencyID="NOK">239</cbc:PriceAmount>
    </cac:Price>
  </cac:InvoiceLine>
  <cac:InvoiceLine>
    <cbc:ID>4</cbc:ID>
    <cbc:InvoicedQuantity unitCode="KGM">62.75</cbc:InvoicedQuantity>
    <cbc:LineExtensionAmount currencyID="NOK">1176.56</cbc:LineExtensionAmount>
    <cac:OrderLineReference>
      <cbc:LineID>4</cbc:LineID>
    </cac:OrderLineReference>
    <cac:TaxTotal>
      <cbc:TaxAmount currencyID="NOK">264.73</cbc:TaxAmount>
    </cac:TaxTotal>
    <cac:Item>
      <cbc:Name>Kaffe</cbc:Name>
      <cac:SellersItemIdentification>
        <cbc:ID>13005</cbc:ID>
      </cac:SellersItemIdentification>
      <cac:ClassifiedTaxCategory>
        <cbc:ID schemeID="UN/ECE 5305" schemeAgencyID="6">S</cbc:ID>
        <cbc:Percent>25.00</cbc:Percent>
        <cac:TaxScheme>
          <cbc:ID schemeID="UN/ECE 5153" schemeAgencyID="6">VAT</cbc:ID>
        </cac:TaxScheme>
      </cac:ClassifiedTaxCategory>
    </cac:Item>
    <cac:Price>
      <cbc:PriceAmount currencyID="NOK">18.750</cbc:PriceAmount>
    </cac:Price>
  </cac:InvoiceLine>
</Invoice>
役に立ちましたか?

解決

Seems like there was an underlying VB process that messed up my decimal numbers. I added a new test where i subtracted one value (cbc:LineExtensionAmount) with the other (sum of cac:InvoiceLine/cbc:LineExtensionAmount). It gave me a diff of 0.00000000000001. My solution for this was to run Xml-validation as a stand-alone exe-file until I can localize excactly where my problem occurs.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Xsl;
using System.Xml;

namespace test.Transform
{
    class Program
    {
        static void Main(string[] args)
        {

            // Arguments
            // Stylesheet
            // XML-out
            // outpath-xml-path

            if (args.Length != 3)
            {
                Console.WriteLine("parameters Stylesheet XML-out outpath-xml-path");
                return;
            }

            XslCompiledTransform xslt = new XslCompiledTransform();
            xslt.Load(args[0]);

            var xml = new XmlDocument();
            xml.Load(args[1]);

            var xmlDocOut = new XmlDocument();

            using (XmlWriter xmlWriter = xmlDocOut.CreateNavigator().AppendChild())
            {
                xslt.Transform(xml, null, xmlWriter);
            }

            xmlDocOut.Save(args[2]);
        }
    }
}

First argument takes ValidationSchemaPath, second Xml-path, last one output path.

Call it like this:

    public static XmlDocument TestRun2(string xsltPath, string docPath, IReport _report)
    {

        var tempFile = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
        var x = Process.GetCurrentProcess().MainModule;

        Process p = new Process();
        p.StartInfo.FileName = Path.Combine(Path.GetDirectoryName(x.FileName), "Transform.exe");
        _report.API.WriteLog(p.StartInfo.FileName);
        p.StartInfo.Arguments = string.Format("\"{0}\" \"{1}\" \"{2}\"", xsltPath, docPath, tempFile);
        p.StartInfo.UseShellExecute = false;
        p.StartInfo.RedirectStandardOutput = true;
        p.Start();

        string output = p.StandardOutput.ReadToEnd();
        p.WaitForExit();

        _report.API.WriteLog("Output from calling Transform.exe");
        _report.API.WriteLog(output);

        if (!File.Exists(tempFile))
        {
            return null;
        }

        var xd = new XmlDocument();
        xd.Load(tempFile);

        return xd;

    }

}

他のヒント

OK this doesn't quite answer your question but it might solve your problem.

Assuming the XML actually contains a root element:

var xml = 
    @"<root>
    <book>
        <name>Book 1</name>
        <price>25.30</price>
    </book>
    <book>
        <name>Book 2</name>
        <price>20.77</price>
    </book>
    <sum>46.07</sum>
    </root>";

Then you can use LINQ to XML to do everything you need simply:

var doc = XDocument.Parse(xml);

var sum = doc.Descendants("book").Sum(e => Convert.ToDecimal(e.Element("price").Value));
var total = Convert.ToDecimal(doc.Root.Element("sum").Value);

Console.WriteLine("sum: [{0}] total: [{1}] matched: [{2}]", sum, total, sum == total);

The XSLT code that you've linked to is generated using Schematron. It would be easier to tell why you are getting errors if (a) you told us what the errors are, and (b) you showed us the Schematron schema, rather than the XSLT code that it generates. There are over 90 occurrences of "Price" in the code...

Also, I can't see (a) how the book XML and the invoice XML in your question relate to each other, or (b) what clues you have that lead you to think this has anything to do with culture or encoding - which on the face of it seems a rather improbably theory.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top