Пример #1
0
        public void ReadInvoiceBogusNode()
        {
            string      filename = "InvoiceBogusXml.xml";
            InvoiceType doc      = UblDoc <InvoiceType> .Create(filename);

            Assert.AreEqual(null, doc, "Should not be possible to read malformed xml");
        }
Пример #2
0
        public void ReadNorwegianCreditNote()
        {
            string         filename = "BII05 T14 0 gyldig kreditnota med alle elementer.xml";
            CreditNoteType doc      = UblDoc <CreditNoteType> .Create(filename);

            Assert.AreEqual("5645342123", doc.AccountingCustomerParty.Party.PartyLegalEntity[0].CompanyID.Value);
            bool areEqual = UblXmlComparer.IsCopyEqual <CreditNoteType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #3
0
        public void ReadWaybillInternational()
        {
            string      filename = "UBL-Waybill-2.0-Example-International.xml";
            WaybillType doc      = UblDoc <WaybillType> .Create(filename);

            Assert.AreEqual("urn:oasis:names:specification:ubl:xpath:Waybill-2.0:samples-2.0-draft", doc.CustomizationID.Value);
            bool areEqual = UblXmlComparer.IsCopyEqual <WaybillType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #4
0
        public void ReadRemittanceAdvice()
        {
            string filename          = "UBL-RemittanceAdvice-2.0-Example.xml";
            RemittanceAdviceType doc = UblDoc <RemittanceAdviceType> .Create(filename);

            Assert.AreEqual("849FBBCE-E081-40B4-906C-94C5FF9D1AC3", (string)doc.RemittanceAdviceLine[0].BillingReference[0].InvoiceDocumentReference.UUID);
            bool areEqual = UblXmlComparer.IsCopyEqual <RemittanceAdviceType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #5
0
        public void ReadRequestForQuotation()
        {
            string filename             = "UBL-RequestForQuotation-2.0-Example.xml";
            RequestForQuotationType doc = UblDoc <RequestForQuotationType> .Create(filename);

            Assert.AreEqual("56A", doc.Delivery[0].DeliveryAddress.BuildingNumber.Value);
            bool areEqual = UblXmlComparer.IsCopyEqual <RequestForQuotationType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #6
0
        public void ReadQuotation()
        {
            string        filename = "UBL-Quotation-2.0-Example.xml";
            QuotationType doc      = UblDoc <QuotationType> .Create(filename);

            Assert.AreEqual("Busy Street", doc.SellerSupplierParty.Party.PostalAddress.StreetName.Value);
            bool areEqual = UblXmlComparer.IsCopyEqual <QuotationType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #7
0
        public void ReadReceiptAdvice()
        {
            string            filename = "UBL-ReceiptAdvice-2.0-Example.xml";
            ReceiptAdviceType doc      = UblDoc <ReceiptAdviceType> .Create(filename);

            Assert.AreEqual("Heremouthshire", (string)doc.DespatchSupplierParty.Party.PostalAddress.CountrySubentity);
            bool areEqual = UblXmlComparer.IsCopyEqual <ReceiptAdviceType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #8
0
        public void ReadOrderresponseSimple()
        {
            string filename             = "UBL-OrderResponseSimple-2.0-Example.xml";
            OrderResponseSimpleType doc = UblDoc <OrderResponseSimpleType> .Create(filename);

            Assert.AreEqual("Farthing Purchasing Consortia", doc.SellerSupplierParty.Party.PartyTaxScheme[0].RegistrationName.Value);
            bool areEqual = UblXmlComparer.IsCopyEqual <OrderResponseSimpleType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #9
0
        public void ReadOrder()
        {
            string    filename = "UBL-Order-2.0-Example.xml";
            OrderType doc      = UblDoc <OrderType> .Create(filename);

            Assert.AreEqual("*****@*****.**", doc.SellerSupplierParty.Party.Contact.ElectronicMail.Value);
            bool areEqual = UblXmlComparer.IsCopyEqual <OrderType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #10
0
        public void ReadOrderInternational()
        {
            string    filename = "UBL-Order-2.0-Example-International.xml";
            OrderType doc      = UblDoc <OrderType> .Create(filename);

            Assert.AreEqual("Mrs Bouquet", doc.SellerSupplierParty.Party.Contact.Name.Value);
            bool areEqual = UblXmlComparer.IsCopyEqual <OrderType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #11
0
        public void ReadNorwegianInvoice()
        {
            string      filename = "BII04 T10 gyldig faktura med alle elementer.xml";
            InvoiceType doc      = UblDoc <InvoiceType> .Create(filename);

            Assert.AreEqual("Accounting department", doc.AccountingCustomerParty.Party.PostalAddress.Department.Value);
            bool areEqual = UblXmlComparer.IsCopyEqual <InvoiceType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #12
0
        public void ReadForwardingInstructionInternational()
        {
            string filename = "UBL-ForwardingInstructions-2.0-Example-International.xml";
            ForwardingInstructionsType doc = UblDoc <ForwardingInstructionsType> .Create(filename);

            Assert.AreEqual("Mr Fred Churchill", doc.Shipment.Consignment[0].ConsigneeParty.Contact.Name.Value);

            bool areEqual = UblXmlComparer.IsCopyEqual <ForwardingInstructionsType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #13
0
        public void ReadStatement()
        {
            string        filename = "UBL-Statement-2.0-Example.xml";
            StatementType doc      = UblDoc <StatementType> .Create(filename);

            UblLarsen.Ubl2.Udt.AmountType line = doc.StatementLine[0].CreditLineAmount;
            Assert.AreEqual(107.50M, line.Value);
            Assert.AreEqual("GBP", line.currencyID);
            bool areEqual = UblXmlComparer.IsCopyEqual <StatementType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #14
0
        public void ReadInvoice()
        {
            string      filename = "UBL-Invoice-2.0-Example.xml";
            InvoiceType doc      = UblDoc <InvoiceType> .Create(filename);

            string name = doc.AccountingCustomerParty.Party.PartyName[0].Name; //.Value; use implicit string conversion

            Assert.AreEqual(name, "IYT Corporation");

            bool areEqual = UblXmlComparer.IsCopyEqual <InvoiceType>(filename, doc);

            Assert.IsTrue(areEqual, "Written invoice differs from the one read");
        }
Пример #15
0
        public void ReadCreditNote()
        {
            string         filename = "UBL-CreditNote-2.0-Example.xml";
            CreditNoteType doc      = UblDoc <CreditNoteType> .Create(filename);

            string value = doc.AccountingCustomerParty.Party.PartyName[0].Name;

            Assert.AreEqual("IYT Corporation", value);

            bool areEqual = UblXmlComparer.IsCopyEqual <CreditNoteType>(filename, doc);

            Assert.IsTrue(areEqual, "Written UBL doc differs from original");
        }
Пример #16
0
        public void Write1000InvoicesToMem()
        {
            int count = 1000;

            MemoryStream[] buffer = new MemoryStream[count];
            for (int i = 0; i < count; i++)
            {
                buffer[i] = new MemoryStream(0x4000);
            }
            InvoiceType[] docs =
            {
                UblDoc <InvoiceType> .Create("UBL-Invoice-2.0-Example.xml"),
                UblDoc <InvoiceType> .Create("BII04 T10 gyldig faktura med alle elementer.xml")
            };
            // Testrun to initialize just in case this is the only test we run
            using (MemoryStream ms = new MemoryStream(0x4000))
            {
                UblDoc <InvoiceType> .Save(ms, docs[0]);
            }

            // Now the real timed test
            Stopwatch stopWatch = new Stopwatch();

            stopWatch.Start();
            for (int i = 0; i < count; i++)
            {
                UblDoc <InvoiceType> .Save(buffer[i], docs[i % 2]);
            }
            stopWatch.Stop();

            for (int i = 0; i < count; i++)
            {
                buffer[i].Dispose();
            }
            this.TestContext.WriteLine("Time writing {0} invoices to memory: {1}", count, stopWatch.Elapsed.ToString("G"));
        }
        public void SaveImplicitCreatedNorwegianCreditNote()
        {
            Func <decimal, AmountType> newAmountType = v => new AmountType {
                Value = v, currencyID = "NOK"
            };

            // Set global defaults for Ubl documents that get created
            var customizationID = "urn:www.cenbii.eu:transaction:BiiCoreTrdm001:ver1.0:extentionId";
            var profileID       = "urn:www.cenbii.eu:profile:bii05:ver1.0";

            // Set thread local default for all amounts types decending from AmountType
            //Ubl2.Udt.AmountType.TlsDefaultCurrencyID = "NOK";

            // Create a serializable CreditNote instance.
            CreditNoteType doc = new CreditNoteType();

            doc.CustomizationID = customizationID;
            doc.ProfileID       = profileID;
            doc.ID                   = "654321";
            doc.UBLVersionID         = "2.0";
            doc.DocumentCurrencyCode = "NOK";
            doc.IssueDate            = new DateTime(2009, 11, 12, 0, 0, 0, DateTimeKind.Utc);

            // <cac:BillingReference>
            //   <cac:InvoiceDocumentReference>
            //     <cbc:ID>123456</cbc:ID>
            //   </cac:InvoiceDocumentReference>
            // </cac:BillingReference>
            // Becomes:
            doc.BillingReference = new BillingReferenceType[]
            {
                new BillingReferenceType {
                    InvoiceDocumentReference = new DocumentReferenceType {
                        ID = "123456"
                    }
                }
            };

            doc.AccountingSupplierParty = new SupplierPartyType
            {
                Party = new PartyType
                {
                    PartyName = new [] { new PartyNameType {
                                             Name = "Leverandør"
                                         } },
                    PostalAddress = new AddressType
                    {
                        Postbox        = "Postboks 123",
                        StreetName     = "Oslogate",
                        BuildingNumber = "1",
                        CityName       = "Oslo",
                        PostalZone     = "0612",
                        Country        = new CountryType {
                            IdentificationCode = "NO"
                        }
                    },
                    PartyLegalEntity = new PartyLegalEntityType[] { new PartyLegalEntityType {
                                                                        CompanyID = "NO999999999MVA"
                                                                    } },
                    Contact = new ContactType {
                        ID = "O Hansen"
                    },
                }
            };

            // Populating class instance the old way but are still using implicit operator assingnment functions
            doc.AccountingCustomerParty = new CustomerPartyType();
            PartyType p = new PartyType();

            doc.AccountingCustomerParty.Party = p;
            p.PartyIdentification             = new [] { new PartyIdentificationType {
                                                             ID = "456789"
                                                         } };
            p.PartyName    = new PartyNameType[1];
            p.PartyName[0] = new PartyNameType {
                Name = "Kjøper"
            };
            p.PostalAddress                            = new AddressType();
            p.PostalAddress.StreetName                 = "Testveien";
            p.PostalAddress.BuildingNumber             = "1";
            p.PostalAddress.CityName                   = "Frogner";
            p.PostalAddress.PostalZone                 = "2012";
            p.PostalAddress.Country                    = new CountryType();
            p.PostalAddress.Country.IdentificationCode = "NO"; // implicit operator called behind the scenes here
            //p.PostalAddress.Country.IdentificationCode = new CodeType { Value = "NO" };
            p.PartyLegalEntity = new PartyLegalEntityType[] { new PartyLegalEntityType() };
            p.PartyLegalEntity[0].CompanyID = "NO888888888MVA";
            p.Contact = new ContactType {
                ID = "3150bdn"
            };

            TaxTotalType tax = new TaxTotalType();

            doc.TaxTotal = new TaxTotalType[1] {
                tax
            };
            tax.TaxAmount   = newAmountType(112.0M);
            tax.TaxSubtotal = new TaxSubtotalType[1] {
                new TaxSubtotalType()
            };
            tax.TaxSubtotal[0].TaxableAmount = newAmountType(800.0M);
            tax.TaxSubtotal[0].TaxAmount     = newAmountType(112.0M);
            tax.TaxSubtotal[0].TaxCategory   = new TaxCategoryType
            {
                ID        = "AA",
                Percent   = 14.0M,
                TaxScheme = new TaxSchemeType {
                    ID = "VAT"
                }
            };

            doc.LegalMonetaryTotal = new MonetaryTotalType();
            doc.LegalMonetaryTotal.LineExtensionAmount = new AmountType {
                Value = 800.0M, currencyID = "AED"
            };                                                                                                  // Note difi.no doc use "AED" instead of DocumentCurrency code. QA slip.
            doc.LegalMonetaryTotal.TaxExclusiveAmount = new AmountType {
                Value = 800.0M, currencyID = "AED"
            };
            doc.LegalMonetaryTotal.TaxInclusiveAmount = new AmountType {
                Value = 912.0M, currencyID = "AED"
            };
            doc.LegalMonetaryTotal.PayableAmount = new AmountType {
                Value = 912.0M, currencyID = "AED"
            };

            doc.CreditNoteLine    = new CreditNoteLineType[1];
            doc.CreditNoteLine[0] = new CreditNoteLineType
            {
                ID = "1",
                CreditedQuantity = new QuantityType {
                    Value = 8, unitCode = "KGM"
                },
                LineExtensionAmount = newAmountType(800.0M),
                TaxTotal            = new TaxTotalType[] { new TaxTotalType {
                                                               TaxAmount = newAmountType(112.0M)
                                                           } },
                Item = new ItemType
                {
                    Name = "Matprodukt-1",
                    SellersItemIdentification = new ItemIdentificationType {
                        ID = "23456785"
                    },
                    ClassifiedTaxCategory = new TaxCategoryType[]
                    {
                        new TaxCategoryType
                        {
                            ID        = "S",
                            Percent   = 14.0M,
                            TaxScheme = new TaxSchemeType {
                                ID = "VAT"
                            }
                        }
                    }
                },
                Price = new PriceType {
                    PriceAmount = newAmountType(100.0M)
                }
            };

            // save the creditnote to xml
            string filename = "ImplicitCreatedNorwegianCreditNote.xml";

            UblDoc <CreditNoteType> .Save(filename, doc);

            // Compare it with a local copy grabbed from difi.no doc
            bool areEqual = UblXmlComparer.IsCopyEqual <CreditNoteType>("NorwegianCreditNoteFromDifiPdfDoc.xml", doc);

            Assert.AreEqual(areEqual, true, "Written UBL doc differs from original");
        }
Пример #18
0
 public void ReadWrongDocTypeByMistake()
 {
     string         filename = "UBL-Invoice-2.0-Example.xml"; // This is not a credit note, next codeline must fail
     CreditNoteType doc      = UblDoc <CreditNoteType> .Create(filename);
 }
        public void SaveImplicitCreatedNorwegianInvoice()
        {
            Func <decimal, AmountType> newAmountType = v => new AmountType {
                Value = v, currencyID = "NOK"
            };
            var taxVAT = new TaxSchemeType {
                ID = "VAT"
            };
            // Create an invoice using global defaults set above
            InvoiceType doc = new InvoiceType
            {
                CustomizationID = "urn:www.cenbii.eu:transaction:biicoretrdm010:ver1.0",
                ProfileID       = "urn:www.cenbii.eu:profile:bii05:ver1.0",
                ID                   = "123456",
                IssueDate            = new DateTime(2009, 11, 12),
                DocumentCurrencyCode = "NOK",
                OrderReference       = new OrderReferenceType {
                    ID = "Prosjekt 13"
                },
                ContractDocumentReference = new DocumentReferenceType[] { new DocumentReferenceType {
                                                                              ID = "K987654321"
                                                                          } },
                AccountingSupplierParty = new SupplierPartyType
                {
                    Party = new PartyType
                    {
                        PartyName = new PartyNameType[] { new PartyNameType {
                                                              Name = "Leverandør"
                                                          } },
                        PostalAddress = new AddressType
                        {
                            Postbox        = "Postboks 123",
                            StreetName     = "Oslogate",
                            BuildingNumber = "1",
                            CityName       = "Oslo",
                            PostalZone     = "0612",
                            Country        = new CountryType {
                                IdentificationCode = "NO"
                            },
                        },
                        PartyTaxScheme = new PartyTaxSchemeType[]
                        {
                            new PartyTaxSchemeType
                            {
                                CompanyID = "NO999999999MVA",
                                TaxScheme = new TaxSchemeType
                                {
                                    ID = new IdentifierType
                                    {
                                        schemeID       = "UN/ECE 5153",
                                        schemeAgencyID = "6",
                                        Value          = "VAT"
                                    }
                                }
                            }
                        },
                        PartyLegalEntity = new PartyLegalEntityType[]
                        {
                            new PartyLegalEntityType {
                                CompanyID = "999999999"
                            }
                        },
                        Contact = new ContactType {
                            ID = "O Hansen"
                        },
                    }
                },
                AccountingCustomerParty = new CustomerPartyType
                {
                    Party = new PartyType
                    {
                        PartyIdentification = new [] { new PartyIdentificationType {
                                                           ID = "456789"
                                                       } },
                        PartyName = new [] { new PartyNameType {
                                                 Name = "Kjøper"
                                             } },
                        PostalAddress = new AddressType
                        {
                            StreetName     = "Testveien",
                            BuildingNumber = "1",
                            CityName       = "Frogner",
                            PostalZone     = "2012",
                            Country        = new CountryType {
                                IdentificationCode = "NO"
                            }
                        },
                        PartyLegalEntity = new PartyLegalEntityType[]
                        {
                            new PartyLegalEntityType {
                                CompanyID = "NO888888888MVA"
                            }
                        },
                        Contact = new ContactType {
                            ID = "Arne Bjarne Baluba"
                        }
                    }
                },
                Delivery = new DeliveryType[]
                {
                    new DeliveryType
                    {
                        ActualDeliveryDate = new DateTime(2009, 11, 25),
                        DeliveryLocation   = new LocationType
                        {
                            Address = new AddressType
                            {
                                StreetName     = "Testgata",
                                BuildingNumber = "1",
                                CityName       = "Oslo",
                                PostalZone     = "0112",
                                Country        = new CountryType {
                                    IdentificationCode = "NO"
                                }
                            }
                        }
                    }
                },
                PaymentMeans = new PaymentMeansType[]
                {
                    new PaymentMeansType
                    {
                        PaymentMeansCode      = "31",
                        PaymentDueDate        = new DateTime(2009, 11, 27),
                        PaymentID             = new Ubl2.Udt.IdentifierType[] { "1234561" },
                        PayeeFinancialAccount = new FinancialAccountType
                        {
                            ID = "NO9386011117947",
                            FinancialInstitutionBranch = new BranchType
                            {
                                ID = new IdentifierType {
                                    schemeID = "BIC", Value = "DNBANOKK"
                                },
                            }
                        }
                    }
                },
                TaxTotal = new TaxTotalType[]
                {
                    new TaxTotalType
                    {
                        TaxAmount   = newAmountType(962.0M),
                        TaxSubtotal = new TaxSubtotalType[]
                        {
                            new TaxSubtotalType
                            {
                                TaxableAmount = newAmountType(3400.0M),
                                TaxAmount     = newAmountType(850.0M),
                                TaxCategory   = new TaxCategoryType
                                {
                                    ID        = "S",
                                    Percent   = 25.0M,
                                    TaxScheme = taxVAT
                                }
                            },
                            new TaxSubtotalType
                            {
                                TaxableAmount = newAmountType(800.0M),
                                TaxAmount     = newAmountType(112.0M),
                                TaxCategory   = new TaxCategoryType
                                {
                                    ID        = "AA",
                                    Percent   = 8.0M,
                                    TaxScheme = taxVAT
                                }
                            }
                        }
                    }
                },
                LegalMonetaryTotal = new MonetaryTotalType
                {
                    LineExtensionAmount = newAmountType(4200.0M),
                    TaxExclusiveAmount  = newAmountType(4200.0M),
                    TaxInclusiveAmount  = newAmountType(5162.0M),
                    PayableAmount       = newAmountType(5162.0M)
                },
                InvoiceLine = new InvoiceLineType[]
                {
                    new InvoiceLineType
                    {
                        ID = "1",
                        InvoicedQuantity = new  Ubl2.Udt.QuantityType {
                            unitCode = "NMP", Value = 2
                        },
                        LineExtensionAmount = newAmountType(400.0M),
                        AccountingCost      = "200500600",
                        OrderLineReference  = new OrderLineReferenceType[]
                        {
                            new OrderLineReferenceType {
                                LineID = "5"
                            }
                        },
                        TaxTotal = new TaxTotalType[]
                        {
                            new TaxTotalType {
                                TaxAmount = newAmountType(100.0M)
                            }
                        },
                        Item = new ItemType
                        {
                            Name = "Testprodukt 1",
                            SellersItemIdentification = new ItemIdentificationType {
                                ID = "12345670"
                            },
                            ClassifiedTaxCategory = new TaxCategoryType[]
                            {
                                new TaxCategoryType
                                {
                                    ID        = "S",
                                    Percent   = 25.0M,
                                    TaxScheme = taxVAT
                                }
                            }
                        },
                        Price = new PriceType {
                            PriceAmount = newAmountType(200.0M)
                        }
                    },
                    new InvoiceLineType
                    {
                        ID = "2",
                        InvoicedQuantity = new QuantityType {
                            unitCode = "NAR", Value = 20
                        },
                        LineExtensionAmount = newAmountType(3000.0M),
                        AccountingCost      = "200900600",
                        OrderLineReference  = new OrderLineReferenceType[]
                        {
                            new OrderLineReferenceType {
                                LineID = "7"
                            }
                        },
                        TaxTotal = new TaxTotalType[]
                        {
                            new TaxTotalType {
                                TaxAmount = newAmountType(750.0M)
                            }
                        },
                        Item = new ItemType
                        {
                            Name = "Testprodukt 2",
                            SellersItemIdentification = new ItemIdentificationType {
                                ID = "24683432"
                            },
                            ClassifiedTaxCategory = new TaxCategoryType[]
                            {
                                new TaxCategoryType
                                {
                                    ID        = "S",
                                    Percent   = 25.0M,
                                    TaxScheme = taxVAT
                                }
                            }
                        },
                        Price = new PriceType {
                            PriceAmount = newAmountType(150.0M)
                        }
                    },
                    new InvoiceLineType
                    {
                        ID = "3",
                        InvoicedQuantity = new QuantityType {
                            unitCode = "KGM", Value = 8
                        },
                        LineExtensionAmount = newAmountType(800.0M),
                        AccountingCost      = "200600700",
                        OrderLineReference  = new OrderLineReferenceType[]
                        {
                            new OrderLineReferenceType {
                                LineID = "8"
                            }
                        },
                        TaxTotal = new TaxTotalType[]
                        {
                            new TaxTotalType {
                                TaxAmount = newAmountType(112.0M)
                            }
                        },
                        Item = new ItemType
                        {
                            Name = "Matprodukt 1",
                            SellersItemIdentification = new ItemIdentificationType {
                                ID = "23456785"
                            },
                            ClassifiedTaxCategory = new TaxCategoryType[]
                            {
                                new TaxCategoryType
                                {
                                    ID        = "AA",
                                    Percent   = 8.0M,
                                    TaxScheme = taxVAT
                                }
                            }
                        },
                        Price = new PriceType {
                            PriceAmount = newAmountType(100.0M)
                        }
                    }
                }
            };

            string filename = "SampleImplicitInvoice.xml";

            UblDoc <InvoiceType> .Save(filename, doc);

            // Use schema validation
            string       xmlSchemaFilename = @"..\..\..\UBL-2.1\xsd\maindoc\UBL-Invoice-2.1.xsd";
            string       preloadToAvoidExceptionFilename = @"..\..\..\UBL-2.1\xsd\common\UBL-xmldsig-core-schema-2.1.xsd";
            XmlSchemaSet invoiceSchemaSet = new XmlSchemaSet();

            // invoiceSchemaSet.Add(null, preloadToAvoidExceptionFilename); // bombs out!
            using (XmlTextReader tr = new XmlTextReader(preloadToAvoidExceptionFilename))
            {
                invoiceSchemaSet.Add(XmlSchema.Read(tr, null));
            }
            invoiceSchemaSet.Add(null, xmlSchemaFilename);
            invoiceSchemaSet.Compile();

            XDocument xDoc = XDocument.Load(filename);

            // throw if invalid
            System.Xml.Schema.Extensions.Validate(xDoc, invoiceSchemaSet, null);
        }