在 coldfusion 中一次更新多个 xml 节点?

Update multiple xml nodes at once in coldfusion?

我有一个 xml 文档,我想一次更新多个节点。我目前是这样做的:

<cfset local.xml = xmlParse(filePath)>
<cfset local.column = xmlSearch(local.xml, "//COLUMN")>
<cfloop from="1" to="#arrayLen(local.column)#" index="i">
  <cfset local.xml.DATA.HEADER.COLUMN[i].xmlAttributes.ID = i>
</cfloop>

这将为每个 COLUMN 节点添加一个属性。但是这里的复杂度是O(n)

所以可以在 O(1) 中做同样的事情?

我这样试过,但它只选择了第一个节点:

<cfset local.xml = xmlParse(filePath)>
<cfset local.xml.DATA.HEADER.COLUMN.xmlAttributes.ID = 1>

XML 样本:

<?xml version="1.0" encoding="UTF-8"?>
<DATA>
  <HEADER>
    <COLUMN/>
    <COLUMN/>
    <COLUMN/>
    <COLUMN/>
    <COLUMN/>
    <COLUMN/>
  </HEADER>
</DATA>

请帮忙。提前致谢。

This will add a attribute to each COLUMN node. But here the complexity is O(n).

So it is possible to do the same in O(1)?

没有。

您想对 N 个节点中的每一个做一些事情。不管怎么转都是O(n)

你可以让它看起来好一点,但仅此而已。

<cfset local.xml = XmlParse(filePath)>
<cfset local.columns = XmlSearch(local.xml, "//COLUMN")>

<cfloop array="#local.columns#" index="local.col">
  <cfset local.col.xmlAttributes.ID = i>
</cfloop>

如果想加快进程,有两种可能:

  1. 如果添加一个 ID(基本上只是一个计数器)是您真正要做的……想想干脆不做。它看起来像一个非常无用的操作。 XML 节点具有自然顺序,它们不需要说明其位置的属性。
  2. 使用更快的 XML 处理工具来完成。 XSLT could be worth a try,在任何情况下都适用于复杂的转换。

要按升序为所有 <COLUMN> 元素提供 ID,您可以使用此转换:

<!-- sample.xsl -->
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="COLUMN">
        <xsl:copy>
            <xsl:attribute name="ID">
                <xsl:value-of select="count(preceding-sibling::COLUMN) + 1" />
            </xsl:attribute>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
</xsl:transform>

和这个 ColdFusion 调用

<cfset outputXml = XmlTransform(xmlFilePath, ExpandPath("sample.xsl"))>

...但如果这实际上比 <cfloop> 快,则您必须自己衡量。