Вывод столбца XML
Я работаю над консольной программой для создания XML-файла с использованием базы данных SQL Server и .NET.
В настоящее время я застрял в коде для создания правильного файла XML. Поскольку мой Categoriesузел неправильно идентифицируется как формат XML, когда я открываю файл в Блокноте, и в результате я не могу его правильно использовать.
Что нужно, так это:
Создайте правильные теги XML,
Categoriesкак показано ниже, и не должны включать какие-либо специальные символы при открытии в любом блокноте.Если у меня есть несколько идентификаторов сайтов (местоположений), как я могу выполнить цикл for из моей таблицы SQL с моим кодом.
Dim dsXmlDoc As XmlDocument = New XmlDocument() ds.Tables(0).TableName = "Inv" dsXmlDoc.LoadXml(ds.GetXml()) Dim xmlInner As XmlElement = CType(xmlDoc.SelectSingleNode("/Root/"), XmlElement)xmlInner.AppendChild(xmlDoc.ImportNode(dsXmlDoc.DocumentElement, True))
Ответы
Думаю будет так:
WITH x AS (
SELECT
A.[ORDER ID],
RIGHT(A.[POS ID], 2) AS [LesseePOSNumber],
REPLACE(A.[BUSINESS DATE],'-','') + '-' + A.[RECEIPT NUMBER] AS [InvoiceNumber],
'1' AS [DocumentType],
CAST(A.[BUSINESS DATE] AS datetime) + CAST(A.[START SALE TIME] AS DATETIME) AS [TransactionDateTime],
SUM(A.ITEM) AS [TotalNumberOfItems],
SUM(A.[TOTAL AMOUNT] - A.[TOTAL TAX]) AS [TransactionTotalWithoutVAT],
SUM(A.[TOTAL TAX]) AS [VATTotalAmount],
'1' AS [PaymentType],
'4' AS [Currency]
FROM
(
SELECT
T1.[storeId] AS [STORE NO]
,CONVERT(date,CONVERT(varchar(15),T1.businessDate,101)) AS [BUSINESS DATE]
,FORMAT(CONVERT(datetime,SUBSTRING(T1.startSaleTime,1,2) + ':' + SUBSTRING(T1.startSaleTime,3,2) + ':' + SUBSTRING(T1.startSaleTime,5,2), 121), 'h:mm:ss') AS [START SALE TIME]
,CASE WHEN (T1.Type) = 'TRX_Refund' OR (T1.Type) = 'TRX_Overring' THEN CAST(T1.[totalAmount] AS decimal(16,2)) * -1 ELSE CAST(T1.[totalAmount] AS decimal(16,2)) END AS [TOTAL AMOUNT]
,CASE WHEN (T1.Type) = 'TRX_Refund' OR (T1.Type) = 'TRX_Overring' THEN 0 ELSE 1 END AS [GC]
,CASE WHEN (T1.Type) = 'TRX_Refund' OR (T1.Type) = 'TRX_Overring' THEN CAST(T1.[totalTax] AS decimal(16,2)) * -1 ELSE CAST(T1.[totalTax] AS decimal(16,2)) END AS [TOTAL TAX]
,T1.NodeId AS [POS ID]
,T1.[receiptNumber] AS [RECEIPT NUMBER]
,T1.orderId AS [ORDER ID]
,
(
SELECT SUM(CASE WHEN CAST(T2.totalPrice AS float) > 0.00 THEN 1 ELSE 0 END)
FROM [McDonalds_STG].[dbo].[ITEMLEVEL] T2
WHERE T2.orderId = T1.orderId
) AS [ITEM]
FROM [McDonalds_STG].[dbo].[Orders] T1
) A
GROUP BY
A.[STORE NO],
A.[BUSINESS DATE],
A.[POS ID],
A.[RECEIPT NUMBER],
A.[START SALE TIME],
A.[ORDER ID]
)
SELECT
x.[LesseePOSNumber],
x.[InvoiceNumber],
x.[DocumentType],
x.[TransactionDateTime],
x.[TotalNumberOfItems],
x.[TransactionTotalWithoutVAT],
x.[VATTotalAmount],
x.[PaymentType],
x.[Currency],
(
SELECT
49 AS [ID],
(CAST(T1.[totalAmount] AS decimal(16,2)) - CAST(T1.[totalTax] AS decimal(16,2)) ) AS [Total]
FROM [Order] T2
WHERE T2.orderId = x.[ORDER ID]
FOR XML PATH('Category'), TYPE
) As Categories
FROM x
FOR XML PATH ('Invoice'), root ('Invoices')
Здесь по-прежнему есть некоторые возможности для значительного разумного рефакторинга (обработка даты / строки / даты требует отбрасывания и повторения без использования строк, где это возможно), и может потребоваться исправление опечаток; это непростой для чтения SQL, и я не ожидаю, что он просто вставится прямо в SSMS и будет работать без каких-либо настроек!
Обратите внимание, что вы ГРУППИРУЕТЕ ПО МАГАЗИНУ НЕТ, но, похоже, вы не используете его
Попробуйте xml linq:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
Dictionary<string, XElement> dict = doc.Descendants("Invoice")
.GroupBy(x => (string)x.Element("LesseePOSNumber"), y => y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
string lesseePOSNumber = "1";
string id = "29";
int total = 3000;
if (dict.ContainsKey(lesseePOSNumber))
{
XElement categories = new XElement("Categories", new XElement("Category", new object[] {
new XElement("ID", id),
new XElement("Total", total)
}));
dict[lesseePOSNumber].Add(categories);
}
}
}
}