使用 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)。