使用 Node.JS 编辑 XML 个文件
Editing XML files with Node.JS
如你所见,我们有这个 XML
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<GetECConfigResponse xmlns="urn:ecs.wsapi.broadon.com">
<Version>2.0</Version>
<DeviceId>4498122730</DeviceId>
<MessageId>ECDK-4498122730-39653600512638909</MessageId>
<TimeStamp>1599408189821</TimeStamp>
<ErrorCode>0</ErrorCode>
<ServiceStandbyMode>false</ServiceStandbyMode>
<ContentPrefixURL>http://example.com</ContentPrefixURL>
<UncachedContentPrefixURL>http://example.com</UncachedContentPrefixURL>
<SystemContentPrefixURL>http://example.com</SystemContentPrefixURL>
<SystemUncachedContentPrefixURL>http://example.com</SystemUncachedContentPrefixURL>
<EcsURL>http://example.com</EcsURL>
<IasURL>http://example.com</IasURL>
<CasURL>http://example.com</CasURL>
<NusURL>http://example.com</NusURL>
</GetECConfigResponse>
</soapenv:Body>
</soapenv:Envelope>
我这样做是为了根据用户的 POST 主体编辑 xml 中的内容,但我必须编辑我想要的内容,并将其变成 XML再次返回并将其作为响应发送,因为 Node.JS 无法在不转换为 JS 或 JSON
的情况下直接编辑 XML
const xmlParser = require("xml2json");
var json2xml = require("json2xml");
// Current time in epoch
function currentEpoch() {
const now = Date.now()
return now
}
// Read the XML file
fs.readFile("./ecs/ecommercesoap/getecconfigresponse.xml", function (err, data) {
// Convert the XML to JSON
const xmlObj = xmlParser.toJson(data, {
object: true
})
// Get the user's body details
var deviceId = req.body["DeviceId"]
// Change XML index depending on the user
xmlObj["soapenv:Envelope"]["soapenv:Body"]["GetECConfigResponse"]["DeviceId"] = deviceId
xmlObj["soapenv:Envelope"]["soapenv:Body"]["GetECConfigResponse"]["TimeStamp"] = currentEpoch().toString()
这是它再次将 xmlObj 转换回 xml 的地方
// Convert the JSON to XML and finalize it
const finalXml = xmlParser.toXml(xmlObj)
// Set the response's type as application/xml
res.type('application/xml');
// Sending the completely edited XML back to the user
res.send(finalXml)
如您所见,转换发生时输出会发生变化。下面的 XML 是在编辑并从 JSON 解析回 XML 之后的。如果您注意到,<?xml version="1.0" encoding="utf-8"?>
也被删除了,这不应该被删除。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<GetECConfigResponse xmlns="urn:ecs.wsapi.broadon.com" Version="2.0" DeviceId="4498122730" MessageId="ECDK-4498122730-39653600512638909" TimeStamp="1599505063565" ErrorCode="0" ServiceStandbyMode="false" ContentPrefixURL="http://example.com" UncachedContentPrefixURL="http://example.com" SystemContentPrefixURL="http://example.com" SystemUncachedContentPrefixURL="http://example.com" EcsURL="http://example.com" IasURL="http://example.com" CasURL="http://example.com" NusURL="http://example.com"/>
</soapenv:Body>
</soapenv:Envelope>
所以我想知道我能做些什么来解决这个问题,原始标签中的标签以 <>
开头和结尾,而编辑后的标签甚至没有。长话短说,一堆东西变了。我也尝试 xml2js
而不是 xml2json
但输出仍然相同。我只希望我的输出与原始文件完全相同,但我的东西发生了变化。
在我们的项目中,我们还必须处理在 NodeJS 中手动修改 soap/xml - 我们最近切换到 fast-xml-parser 并且对此非常满意。我接受了您的示例输入并使用了以下代码:
const xmlToJsonParser = require('fast-xml-parser');
const options = {
ignoreAttributes: false,
ignoreNameSpace: false,
parseNodeValue: true,
parseAttributeValue: true,
trimValues: true,
};
// xmlData refers to the xml-string
const tObj = xmlToJsonParser.getTraversalObj(xmlData, options);
const jsonObj = xmlToJsonParser.convertToJson(tObj, options);
// modify json
jsonObj["soapenv:Envelope"]["soapenv:Body"]["GetECConfigResponse"].DeviceId = 123456;
const JsonToXmlParser = require("fast-xml-parser").j2xParser;
const parser = new JsonToXmlParser({format: true, ignoreAttributes: false});
const xml = parser.parse(jsonObj);
console.log(xml);
它产生:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<GetECConfigResponse xmlns="urn:ecs.wsapi.broadon.com">
<Version>2</Version>
<DeviceId>123456</DeviceId>
<MessageId>ECDK-4498122730-39653600512638909</MessageId>
<TimeStamp>1599408189821</TimeStamp>
<ErrorCode>0</ErrorCode>
<ServiceStandbyMode>false</ServiceStandbyMode>
<ContentPrefixURL>http://example.com</ContentPrefixURL>
<UncachedContentPrefixURL>http://example.com</UncachedContentPrefixURL>
<SystemContentPrefixURL>http://example.com</SystemContentPrefixURL>
<SystemUncachedContentPrefixURL>http://example.com</SystemUncachedContentPrefixURL>
<EcsURL>http://example.com</EcsURL>
<IasURL>http://example.com</IasURL>
<CasURL>http://example.com</CasURL>
<NusURL>http://example.com</NusURL>
</GetECConfigResponse>
</soapenv:Body>
</soapenv:Envelope>
剩下的就是在 xml-header 前面添加,因为他们已决定从解析器中排除此功能 (https://github.com/NaturalIntelligence/fast-xml-parser/issues/184)。
如你所见,我们有这个 XML
<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<GetECConfigResponse xmlns="urn:ecs.wsapi.broadon.com">
<Version>2.0</Version>
<DeviceId>4498122730</DeviceId>
<MessageId>ECDK-4498122730-39653600512638909</MessageId>
<TimeStamp>1599408189821</TimeStamp>
<ErrorCode>0</ErrorCode>
<ServiceStandbyMode>false</ServiceStandbyMode>
<ContentPrefixURL>http://example.com</ContentPrefixURL>
<UncachedContentPrefixURL>http://example.com</UncachedContentPrefixURL>
<SystemContentPrefixURL>http://example.com</SystemContentPrefixURL>
<SystemUncachedContentPrefixURL>http://example.com</SystemUncachedContentPrefixURL>
<EcsURL>http://example.com</EcsURL>
<IasURL>http://example.com</IasURL>
<CasURL>http://example.com</CasURL>
<NusURL>http://example.com</NusURL>
</GetECConfigResponse>
</soapenv:Body>
</soapenv:Envelope>
我这样做是为了根据用户的 POST 主体编辑 xml 中的内容,但我必须编辑我想要的内容,并将其变成 XML再次返回并将其作为响应发送,因为 Node.JS 无法在不转换为 JS 或 JSON
的情况下直接编辑 XMLconst xmlParser = require("xml2json");
var json2xml = require("json2xml");
// Current time in epoch
function currentEpoch() {
const now = Date.now()
return now
}
// Read the XML file
fs.readFile("./ecs/ecommercesoap/getecconfigresponse.xml", function (err, data) {
// Convert the XML to JSON
const xmlObj = xmlParser.toJson(data, {
object: true
})
// Get the user's body details
var deviceId = req.body["DeviceId"]
// Change XML index depending on the user
xmlObj["soapenv:Envelope"]["soapenv:Body"]["GetECConfigResponse"]["DeviceId"] = deviceId
xmlObj["soapenv:Envelope"]["soapenv:Body"]["GetECConfigResponse"]["TimeStamp"] = currentEpoch().toString()
这是它再次将 xmlObj 转换回 xml 的地方
// Convert the JSON to XML and finalize it
const finalXml = xmlParser.toXml(xmlObj)
// Set the response's type as application/xml
res.type('application/xml');
// Sending the completely edited XML back to the user
res.send(finalXml)
如您所见,转换发生时输出会发生变化。下面的 XML 是在编辑并从 JSON 解析回 XML 之后的。如果您注意到,<?xml version="1.0" encoding="utf-8"?>
也被删除了,这不应该被删除。
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<GetECConfigResponse xmlns="urn:ecs.wsapi.broadon.com" Version="2.0" DeviceId="4498122730" MessageId="ECDK-4498122730-39653600512638909" TimeStamp="1599505063565" ErrorCode="0" ServiceStandbyMode="false" ContentPrefixURL="http://example.com" UncachedContentPrefixURL="http://example.com" SystemContentPrefixURL="http://example.com" SystemUncachedContentPrefixURL="http://example.com" EcsURL="http://example.com" IasURL="http://example.com" CasURL="http://example.com" NusURL="http://example.com"/>
</soapenv:Body>
</soapenv:Envelope>
所以我想知道我能做些什么来解决这个问题,原始标签中的标签以 <>
开头和结尾,而编辑后的标签甚至没有。长话短说,一堆东西变了。我也尝试 xml2js
而不是 xml2json
但输出仍然相同。我只希望我的输出与原始文件完全相同,但我的东西发生了变化。
在我们的项目中,我们还必须处理在 NodeJS 中手动修改 soap/xml - 我们最近切换到 fast-xml-parser 并且对此非常满意。我接受了您的示例输入并使用了以下代码:
const xmlToJsonParser = require('fast-xml-parser');
const options = {
ignoreAttributes: false,
ignoreNameSpace: false,
parseNodeValue: true,
parseAttributeValue: true,
trimValues: true,
};
// xmlData refers to the xml-string
const tObj = xmlToJsonParser.getTraversalObj(xmlData, options);
const jsonObj = xmlToJsonParser.convertToJson(tObj, options);
// modify json
jsonObj["soapenv:Envelope"]["soapenv:Body"]["GetECConfigResponse"].DeviceId = 123456;
const JsonToXmlParser = require("fast-xml-parser").j2xParser;
const parser = new JsonToXmlParser({format: true, ignoreAttributes: false});
const xml = parser.parse(jsonObj);
console.log(xml);
它产生:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<GetECConfigResponse xmlns="urn:ecs.wsapi.broadon.com">
<Version>2</Version>
<DeviceId>123456</DeviceId>
<MessageId>ECDK-4498122730-39653600512638909</MessageId>
<TimeStamp>1599408189821</TimeStamp>
<ErrorCode>0</ErrorCode>
<ServiceStandbyMode>false</ServiceStandbyMode>
<ContentPrefixURL>http://example.com</ContentPrefixURL>
<UncachedContentPrefixURL>http://example.com</UncachedContentPrefixURL>
<SystemContentPrefixURL>http://example.com</SystemContentPrefixURL>
<SystemUncachedContentPrefixURL>http://example.com</SystemUncachedContentPrefixURL>
<EcsURL>http://example.com</EcsURL>
<IasURL>http://example.com</IasURL>
<CasURL>http://example.com</CasURL>
<NusURL>http://example.com</NusURL>
</GetECConfigResponse>
</soapenv:Body>
</soapenv:Envelope>
剩下的就是在 xml-header 前面添加,因为他们已决定从解析器中排除此功能 (https://github.com/NaturalIntelligence/fast-xml-parser/issues/184)。