2

我必须进行不区分大小写的 XML 搜索。我编写了运行良好translate的 XPath 表达式,但是当我在 XPath 表达式中使用该函数时出现错误。以下是运行良好的 XPath 表达式:

string upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
string lower = "abcdefghijklmnopqrstuvwxyz";

string xpath = "/data/item[AID/@iskey='true' and AID/text() = 'fep'][not(*[@iskey][local-name() != 'AID' ])]";       

string xpath1 = "/data/item[translate('Aid','" + upper + "','" + lower + "')]";

这是我的 XML:

<?xml version="1.0" encoding="utf-8"?>
<data>
<item>
 <AID iskey="true">fep</AID>
  <account>MS</account>
  </item>
</data>

我想将translate函数放在第一个 XPath 表达式中,如下所示:

 string xpath = "/data/item[translate('AID','" + upper + "','" + lower + "')/@iskey='true' and translate('AID','" + upper + "','" + lower + "')/text() = 'fep'][not(*[@iskey][local-name() != translate('aid','" + upper + "','" + lower + "') ])]";

当我这样做时,我收到以下错误:

表达式必须计算为节点集。

这个 xpath 对我来说很好用。

 string col="AID"; 
 string xpath = "/data/item[col/@iskey='true' and col/text() = 'fep'][not(*[@iskey][local-name() != 'col' ])]";   

现在我的要求是 col 值在任何情况下都可以是大写或小写,所以我想要更改我的 xpath,无论 xml 中存在哪种情况下的数据,它都会返回结果。如果用户提供援助或援助或援助,它会返回结果给我。

4

2 回答 2

1

该错误是由于在您的 XPath 表达式中您有一个像这样的位置步骤:

item['aid'/@isKey = 'true' ...]

子表达式:

'aid'/@isKey

在 XPath 中在语法上是非法的,因为运算符的左侧/必须是一个节点集——这里它只是一个字符串。

您希望有一个这样的 XPath 表达式 - 而不是您目前正在生成的那个

/data/item
       [*[translate(name(), 'aid', 'AID') = 'AID']/@iskey='true'
      and
        *[translate(name(), 'aid', 'AID') = 'AID'] = 'fep'
         ]
          [not(*[@iskey]
                [translate(name(), 'aid', 'AID') != 'AID']
             )
         ]

基于 XSLT 的验证

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:variable name="vLower" select="'aid'"/>
 <xsl:variable name="vUpper" select="'AID'"/>

 <xsl:template match="node()|@*">
     <xsl:copy-of select=
      "/data/item
           [*[translate(name(), 'aid', 'AID') = 'AID']/@iskey='true'
          and
            *[translate(name(), 'aid', 'AID') = 'AID'] = 'fep'
             ]
              [not(*[@iskey]
                    [translate(name(), 'aid', 'AID') != 'AID']
                 )
             ]
      "/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时:

<data>
    <item>
        <AID iskey="true">fep</AID>
        <account>MS</account>
    </item>
</data>

计算 XPath 表达式并将选定节点(在本例中只有一个)复制到输出

<item>
   <AID iskey="true">fep</AID>
   <account>MS</account>
</item>

更新

OP 很难理解这个解决方案。这是一个示例,向他展示了该解决方案适用于字符串“aid”的任何大写形式:

当上述转换应用于 XML 文档时,该文档包含的元素名称是“aid”的任何大写形式——例如:

<data>
    <item>
        <aId iskey="true">fep</aId>
        <account>MS</account>
    </item>
</data>

再次产生预期的结果

<item>
   <aId iskey="true">fep</aId>
   <account>MS</account>
</item>

更新 2

OP 仍然不理解解决方案,并声称对于特定的 XML 文档——下面提供——“我使用了你的表达式,它返回 null ”

这是 OP 评论中提供的 XML 文档:

<data>
    <item>
        <aId iskey="true">fep</aId>
        <account>FG</account>
    </item>
</data>

当针对该文档运行相同的 XSLT 验证时,再次选择并输出正确的元素

<item>
   <aId iskey="true">fep</aId>
   <account>FG</account>
</item>
于 2012-07-06T16:20:41.233 回答
0

尝试使用联合,而不是 using translate()(aid|AID)

新的 xpath:

/data/item[(aid|AID)/@iskey='true' and (aid|AID)/text() = 'fep'][not(*[@iskey][local-name() != 'AID' and local-name() != 'aid'])]
于 2012-07-06T15:33:48.043 回答