【问题标题】:Editing XML files with Node.JS使用 Node.JS 编辑 XML 文件
【发布时间】:2020-12-26 04:55:14
【问题描述】:

如您所见,我们有这个 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 直接编辑 XML 而不转换为 JS 或 JSON

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 之后的。如果你注意到了,&lt;?xml version="1.0" encoding="utf-8"?&gt; 也被删除了,这是不应该的。

<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>

所以我想知道我能做些什么来解决这个问题,标签在原始标签中以&lt;&gt; 开头和结尾,而经过编辑的标签甚至没有。长话短说,一堆东西变了。我也尝试了xml2js 而不是xml2json,但输出仍然相同。我只希望我的输出与原始文件完全相同,但我的东西发生了变化。

【问题讨论】:

  • 你为什么不使用类似soap的包?
  • 我现在用的没问题,但也不是这样。
  • 我无法找到将 XML 转换为 JSON 并再次返回的任何充分理由。为什么不简单地在 XSLT 中进行转换?

标签: node.js json xml soap


【解决方案1】:

在我们的项目中,我们还必须在 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 文件,因为当我在问题中使用我的 fs 代码尝试它时,我收到了一个奇怪的错误xmlData = xmlData.replace(/(\r\n)|\n/, " "); TypeError: xmlData.replace is not a function
  • 您是否在回调中检查了err?在继续之前,您需要确保它没有被定义。
  • 您可以在阅读文件后添加console.log(xmlData)吗?
  • 感谢您解决问题!你是最棒的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-17
  • 1970-01-01
  • 2012-06-28
  • 2014-12-25
  • 2011-09-23
相关资源
最近更新 更多