2013-04-08 64 views
3

我有一个XML这样的:如何获得属性值,如果它们不等于某些值?

<movies> 
    <movie name="aaa"> 
     ... 
    </movie> 
    <movie name="bbb"> 
     ... 
    </movie> 
    <movie name="ccc"> 
     ... 
    </movie> 
    <movie name="ddd"> 
     ... 
    </movie> 
    <movie name="eee"> 
     ... 
    </movie> 
</movies> 

我想获得该电影的名字,如果它不是“AAA”或“BBB”,或“DDD”。所以,我想我的输出是:

ccc 
eee 

因为我有一些限制,我不认为这是适合使用“的xsl:如果” ..我写我喜欢的XSLT(我使用XSLT 1.0 ):

<xsl:value-of select="movies/movie/@name[not(self::aaa) and not(self::bbb) and not(self:ddd)]"/> 

但是,编译器抱怨有这sentence..and我想不出一个语法错误,为什么..

所以可能有人帮助我吗?非常感谢!!

回答

3

试试这个XPath表达式:

movies/movie[@name!='aaa' and @name!='bbb' and @name!='ddd']/@name 

或者这一个:

movies/movie/@name[.!='aaa' and .!='bbb' and .!='ddd'] 

后者更短,但前者可以很容易地扩展到检查其他的回报不仅名字,但整个<movie>元素 - 最后删除/@name。或者如果你想要第二个,只需在最后加上/..即可。

+0

嗨,谢谢你的回答。第一个解决方案奏效。其实我也想出了那个,但是因为我是xslt的新手,我想知道第一个xpath是否会让选择变慢? – 2013-04-08 22:13:21

+0

@ D.Q .:欢迎您:)如果您真的只需*名称属性,那么第二个表达式就是要走的路。如果你需要整个'',那么你*必须使用这样的东西:' Name:
描述:'。或者更好:''。我无法进一步帮助您,因为我不知道XML的结构,也不了解您的转换的预期结果。 – 2013-04-08 22:22:02

+0

我明白了你的观点:)并且还有一个问题,如果我还有其他几个限制,例如我需要排除的名字的数量有点大,比如8或10.还有什么其他方式可以处理它,这样我就不会有很长的xpath表达式,这对于进一步的扩展来说不是很好。 .. – 2013-04-08 22:30:49

2

考虑使用像这样的表达式,如果有太多的一对多值比较:

/*/movie[not(contains('|aaa|bbb|ddd|', concat('|', @name, '|)))]/@name 

这将选择任何movie元件的任何name属性,该属性是的顶部元件的子XSLT文档,其值(name属性)不是字符串值为"|aaa|bbb|ddd|"的管道分隔列表中的字符串之一。

+0

...并且其值是** NOT **管道分隔列表中的一个字符串... – 2013-04-09 10:14:21

+0

@ alex-shesterov,感谢您接收此信息。现在更正。 – 2013-04-09 14:32:52

+0

谢谢@DimitreNovatchev提供这种优秀的解决方案! – 2013-04-09 14:53:10

相关问题