XPath在ColdFusion-8中查找具有某些名称的子节点的父节点

时间:2015-02-18 20:39:56

标签: xml xpath coldfusion coldfusion-8

使用Coldfusion 8和XMLSearch()我正在尝试构建一个XPath()语句,该语句将查找父项的特定子项的出现。

我的父母combinationCharts可以有barline或两者都有的孩子。我需要能够找到bar no line的三种组合; line no bar;或bar and line我已经尝试了几次

的迭代
<cfset myBarLineChart = XMLSearch(cleanedXML, "//*[descendant::combinationChartTypes][contains(name(),'bar') and contains(name(),'line')]" )>

使用descendantchild//*等的不同组合。不知何故,我无法找到获得任何结果的魔法顺序。

有效的是:

<cfset myBarChart = XMLSearch(cleanedXML, "//*[name()='combinationChartTypes']//*[name()='bar']")>  

<cfset myLineChart = XMLSearch(cleanedXML, "//*[name()='combinationChartTypes']//*[name()='line']")> 

但问题是当combinationChartTypes同时包含barline

时,它们会重复计算

我尝试过以下解决方案:

Recursive Query of XML in ColdFusion 8 to find unknown number of children sub levels

Is it possible in XPath to find parent when none of the children met some criteria

即使在阅读并重读之后,一切都无济于事: http://www.w3schools.com/xpath/xpath_axes.asp

http://zvon.org/comp/r/tut-XPath_1.html#Pages~List_of_XPaths

任何帮助指出我正确的方向或直接解决这个问题都会非常感激!

以下是我正在搜索的示例xml:

<?xml version="1.0" encoding="UTF-8"?>
<report expressionlocale="en" ignorefiltercontext="false" xmlns="http://www.w3.org/1999/xhtml"><reportName>Revenue by GO Subsidiary 2005</reportName>
...
<!--- Example of line chart only --->
<combinationChartTypes>
    <line bordercolor="black" datapointsize="4" pointchartdatapointshape="verticalLine" showabsolutevalues="true" showborders="false" showline="false" showvalues="false" usenumericalaxis="numericalAxisY1" valuetype="absolute">
        <chartNodes>
            <chartNode>
                <chartNodeMembers>
                    <chartNodeMember refdataitem="Example of line chart only">
                        <chartContents>
                            <chartTextItem>
                                <dataSource>
                                </dataSource>
                            </chartTextItem>
                        </chartContents>
                    </chartNodeMember>
                </chartNodeMembers>
            </chartNode>
        </chartNodes>
    </line>
</combinationChartTypes>
...
<!--- Example of bar chart only --->
...
<combinationChartTypes>
    <bar>
        <chartNodes>
            <chartNode>
                <chartNodeMembers>
                    <chartNodeMember refdataitem="Example of bar chart only">
                        <chartContents>
                            <chartTextItem>
                                <dataSource>
                                </dataSource>
                                    <conditionalDataSources refvariable="Report Language1">
                                    <conditionalDataSource refvariablevalue="de">
                                        <staticValue>Einnahmen (Millionen)</staticValue>
                                    </conditionalDataSource>
                                    <conditionalDataSource refvariablevalue="fr">
                                        <staticValue>Revenus (millions)</staticValue>
                                    </conditionalDataSource>
                            </chartTextItem>
                        </chartContents>
                    </chartNodeMember>
                </chartNodeMembers>
            </chartNode>
        </chartNodes>
    </bar>
</combinationChartTypes>
...
<!--- Example of bar and line chart mixed --->
...
<combinationChartTypes>
    <bar>
        <chartNodes>
            <chartNode>
                <chartNodeMembers>
                    <chartNodeMember refdataitem="example of bar and line chart mixed">
                        <chartContents>
                            <chartTextItem>
                                <dataSource>
                                </dataSource>
                                    <conditionalDataSources refvariable="Report Language1">
                                    <conditionalDataSource refvariablevalue="de">
                                        <staticValue>Einnahmen (Millionen)</staticValue>
                                    </conditionalDataSource>
                                    <conditionalDataSource refvariablevalue="fr">
                                        <staticValue>Revenus (millions)</staticValue>
                                    </conditionalDataSource>
                            </chartTextItem>
                        </chartContents>
                    </chartNodeMember>
                </chartNodeMembers>
            </chartNode>
        </chartNodes>
    </bar>
    <line bordercolor="black" datapointsize="4" pointchartdatapointshape="verticalLine" showabsolutevalues="true" showborders="false" showline="false" showvalues="false" usenumericalaxis="numericalAxisY1" valuetype="absolute">
        <chartNodes>
            <chartNode>
                <chartNodeMembers>
                    <chartNodeMember refdataitem="Same quarter, 2004">
                        <chartContents>
                            <chartTextItem>
                                <dataSource>
                                </dataSource>
                            </chartTextItem>
                        </chartContents>
                    </chartNodeMember>
                </chartNodeMembers>
            </chartNode>
        </chartNodes>
    </line>
</combinationChartTypes>
...
</report>

如果您想要搜索的文件的完整长丑形式,请访问:http://jsfiddle.net/asheppardwork/3uuaj5jb/

1 个答案:

答案 0 :(得分:1)

您缺少默认命名空间(xmlns="http://www.w3.org/1999/xhtml")。 (你的XML在XHTML命名空间中没有实际是XHTML这一事实是相当可疑的。我认为它的创建过程是破碎的。如果你对此有任何影响,我建议你从那里开始。)

在标准XPath 1.0使用期间,搜索//combinationChartTypes只会打开无名称空间的<combinationChartTypes>个节点

但你没有这些。

现在,在XPath中使用它们之前,通常会注册所需的命名空间URI,但ColdFusion 8并没有提供这样做的方法。 (如果愿意,您可以将http://www.w3.org/1999/xhtml注册为xhtml,然后查询"//xhtml:combinationChartTypes"。)


XmlSearch()自动支持XML源中的名称空间前缀:

<doc xmlns:foo="http://foo">
  <foo:element />
</doc>

<cfset result = XmlSearch(doc, "//foo:element")>

将返回一些东西。但是,对于具有默认命名空间的XML(即没有前缀),情况并非如此。

在这种情况下,你仍然可以回到这个更加繁琐的模式:

<cfset path = "//*[local-name() = 'combinationChartTypes' and *[local-name() = 'bar'] and not(*[local-name() = 'line'])]">
<cfset myBarChart = XMLSearch(cleanedXML, path)>

或者,作为一个肮脏的黑客,你可以逃脱XmlParse(Replace(xml, 'xmlns="namespace-uri-in-question"', '')),然后通常在现在没有名称空间的XML上使用XmlSearch()