在 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>
如果想加快进程,有两种可能:
- 如果添加一个 ID(基本上只是一个计数器)是您真正要做的……想想干脆不做。它看起来像一个非常无用的操作。 XML 节点具有自然顺序,它们不需要说明其位置的属性。
- 使用更快的 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>
快,则您必须自己衡量。
我有一个 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>
如果想加快进程,有两种可能:
- 如果添加一个 ID(基本上只是一个计数器)是您真正要做的……想想干脆不做。它看起来像一个非常无用的操作。 XML 节点具有自然顺序,它们不需要说明其位置的属性。
- 使用更快的 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>
快,则您必须自己衡量。