我正在创建一个允许加载 XML 文件的功能,但在加载它们之前我需要验证它们的内容,我不知道这是否是正确的方法,但我正在考虑首先阅读 XML 以查看其内容和然后用我存储在数据库表中的数据验证它。
目前我开发的是使用 AJAX 和 PHP 加载 XML 文件,如下所示。
这是我用来加载 XML 文件的表单的一部分
<form action="" enctype="multipart/form-data">
<div class="form-group row">
<label for="fileToUpload" class="col-sm-3 col-form-label"> File XML:</label>
<div class="col-sm-8">
<input type="file" name="fileToUpload" id="XmlToUpload" class="btn" accept=".xml" required>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
<button type="button" id="upload" class="btn btn-success">Upload Documents</button>
</div>
</form>
以下是我加载文档并验证其格式的 JQuery 函数
$(document).ready(function(){
$("#upload").on("click", function(){
const ArchivoXml = $("#XmlToUpload").prop('files')[0];
if (ArchivoXml.type !== 'text/xml') {
$('#XmlToUpload').val('');
//$('#pdfToUpload').val('');
alert('Please select the files with the correct format');
return;
}
const datosForm = new FormData;
datosForm.append("XmlToUpload", ArchivoXml);
const filePath="server.php"
//console.log(ArchivoXml);
$.ajax({
type:'POST',
cache: false,
contentType: false,
processData: false,
data: datosForm,
url:filePath
}).done(function(data){
alert(data)
}).fail(function(){
alert('The file could not be loaded')
});
});
});
以下是我指明存储路径的 PHP 代码server.php
<?php
if(isset($_FILES["XmlToUpload"])){
$archivo = $_FILES["XmlToUpload"]["name"];
$ruta ="XML/";
if(move_uploaded_file($_FILES["XmlToUpload"]["tmp_name"],$ruta.$archivo)){
echo "Successfully uploaded";
}else{
echo "Error";
}
}else {
echo "A file was not selected";
}
?>
正如我在问题开头提到的,我需要验证 XML 的内容,并使用在数据库表中找到的信息来验证它。XML 文件的结构将包含以下信息:
<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Voucher Version="3.3" Total="45264.13">
<cfdi:Issuer Rfc="ABC123456AB1" Name="JOHN DOE"/>
<cfdi:Concepts>
<cfdi:Concept UnitValue="93.80">
</cfdi:Concept>
</cfdi:Concepts>
<cfdi:Plugin>
<tfd:Digital Version="1.1" />
</cfdi:Plugin>
</cfdi:Voucher>
这里我有兴趣验证的数据是 Total="45264.13"
和 Rfc="ABC123456AB1"
除此之外,我开始了在 SQLServer 中创建存储过程的任务,以从数据库中获取信息,从而与 XML 数据和数据库中表的字段值进行比较。USE [dbtest]
GO
/****** Object: StoredProcedure [dbo].[sptest]
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[sptest]
AS
BEGIN
Select VTB.RFC as 'RFC',
LRC.QTY as 'QTY',
PL.PRICE as 'Price',
(PL.PRICE *LRC.QTY) * 1.16 as 'Total'
from PACKING RC
inner join VTABLE VTB on VTB.COLUMN = RC.INVOICE
inner join TRANS LRC on (LRC.PACKING = RC.RECID)
inner join PURCH PL on (PL.NUMBER =LRC.NUM and PL.PURCH =RC.PURCH)
END
我希望有人可以指导我使用我正在创建的这个功能。更新:
为了提供更快的验证以使数据等于 XML 的内容,现在我决定在前面获取它们,也就是说,在我加载 XML 的同一 View 中显示它们,如下所示:
<div class="form-group row">
<label for="lblNombreVisita" class="col-sm-3 col-form-label">RFC:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="txtRfc" disabled>
</div>
</div>
<div class="form-group row">
<label for="lblNombreVisita" class="col-sm-3 col-form-label">Total:</label>
<div class="col-sm-8">
<input type="text" class="form-control" id="txtTotal" disabled>
</div>
</div>
<form action="" enctype="multipart/form-data">
<div class="form-group row">
<label for="fileToUpload" class="col-sm-3 col-form-label"> Archivo XML:</label>
<div class="col-sm-8">
<input type="file" name="fileToUpload" id="XmlToUpload" class="btn" accept=".xml" required>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Cancelar</button>
<button type="button" id="upload" class="btn btn-success">Subir Documentos</button>
</div>
</form>
同样,如果有人发现如何验证它们等于在数据库中找到的值,它也是有效的,或者如果它们可以直接使用我在我刚刚添加的文本字段中获得的值进行验证, 也是有效的。
最佳答案
假设您共享的 XML 是传递给 SQL Server 的实际 XML,您将遇到命名空间方面的挑战。它们需要在 XML 中声明,然后在查询数据时再次声明。
这是一个示例,它返回您共享的 Total
和 Rfc
的值。
-- String holding the supplied XML.
DECLARE @my_xml varchar(MAX) =
'<?xml version="1.0" encoding="UTF-8"?>
<cfdi:Voucher Version="3.3" Total="45264.13">
<cfdi:Issuer Rfc="ABC123456AB1" Name="JOHN DOE"/>
<cfdi:Concepts>
<cfdi:Concept UnitValue="93.80"></cfdi:Concept>
</cfdi:Concepts>
<cfdi:Plugin>
<tfd:Digital Version="1.1" />
</cfdi:Plugin>
</cfdi:Voucher>';
-- Remove the XML declaration and add the required namespaces via a "root" wrapper.
-- Note: You could use STUFF to place root after the declaration and keep it, but this was faster.
SELECT
@my_xml = REPLACE ( @my_xml, '<?xml version="1.0" encoding="UTF-8"?>', '' ),
@my_xml = CONCAT ( '<root xmlns:cfdi="uri" xmlns:tfd="uri">', @my_xml, '</root>' );
-- Return the values for Total and Rfc.
SELECT
t.c.value('declare namespace cfdi="uri"; (@Total)[1]', 'decimal(18,2)') AS Total,
t.c.value('declare namespace cfdi="uri"; (cfdi:Issuer/@Rfc)[1]', 'varchar(50)') AS Rfc
FROM ( SELECT CAST ( @my_xml AS xml ) AS xml_data ) AS x
CROSS APPLY x.xml_data.nodes( 'declare namespace cfdi="uri"; //root/cfdi:Voucher' ) t(c);
返回 +----------+--------------+
| Total | Rfc |
+----------+--------------+
| 45264.13 | ABC123456AB1 |
+----------+--------------+
假设我了解您的验证和要求,您可以调整您的存储过程以接受您的 XML 作为参数,然后相应地对其进行验证/处理。这是一个供引用的示例:
CREATE OR ALTER PROCEDURE [dbo].[sptest] (
@my_xml varchar(MAX)
)
AS
BEGIN
DECLARE
@rfc varchar(50), @qty int, @price decimal(18,2), @total decimal(18,2);
/*****************************************/
/* Fetch values for validation */
/*****************************************/
SELECT
@rfc = VTB.RFC AS 'RFC',
@qty = LRC.QTY AS 'QTY',
@price = PL.PRICE AS 'Price',
@total = (PL.PRICE * LRC.QTY) * 1.16 AS 'Total'
FROM PACKING AS RC
INNER JOIN VTABLE AS VTB
ON VTB.COLUMN = RC.INVOICE
INNER JOIN TRANS AS LRC
ON (LRC.PACKING = RC.RECID)
INNER JOIN PURCH AS PL
ON (PL.NUMBER =LRC.NUM and PL.PURCH =RC.PURCH)
/*****************************************/
/* Fetch XML values to validate */
/*****************************************/
DECLARE
@x_rfc varchar(50), @x_total decimal(18,2);
-- Remove the XML declaration and add the required namespaces via a "root" wrapper.
-- Note: You could use STUFF to place root after the declaration and keep it, but this was faster.
SELECT
@my_xml = REPLACE ( @my_xml, '<?xml version="1.0" encoding="UTF-8"?>', '' ),
@my_xml = CONCAT ( '<root xmlns:cfdi="uri" xmlns:tfd="uri">', @my_xml, '</root>' );
-- Return the values for Total and Rfc.
SELECT
@x_total = t.c.value('declare namespace cfdi="uri"; (@Total)[1]', 'decimal(18,2)'),
@x_rfc = t.c.value('declare namespace cfdi="uri"; (cfdi:Issuer/@Rfc)[1]', 'varchar(50)')
FROM ( SELECT CAST ( @my_xml AS xml ) AS xml_data ) AS x
CROSS APPLY x.xml_data.nodes( 'declare namespace cfdi="uri"; //root/cfdi:Voucher' ) t(c);
/*****************************************/
/* Validate and handle XML */
/*****************************************/
IF @rfc = @x_rfc AND @total = @x_total BEGIN
-- Validation Success --
-- Insert your XML to database...
END ELSE BEGIN
-- Validation Failure --
-- Throw and error or whatever you need...
END
END
GO
我在这里做了很多假设(比如你的 XML 和 SELECT 都只包含一条记录),但它应该让你继续前进。
关于javascript - 如何读取 XML 文件并使用表中的数据进行验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67624793/