我是XSLT的新手,我的问题是,是否可以在路径的不同级别使用“或”进行逻辑测试,还是必须以某种方式将其分开?
示例xml:
<LandXML>
<HexagonLandXML>
<Point lineworkFlag="START LINJE">
<PointCode codeLinework="open line">
</PointCode>
</Point>
</HexagonLandXML>
</LandXML>
示例xls:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:landxml="http://www.landxml.org/schema/LandXML-1.2"
xmlns:hexagon="http://xml.hexagon.com/schema/HeXML-1.7"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"
version="1.0"
encoding="UTF-16"
indent="no"
omit-xml-declaration="yes"/>
<xsl:variable name="XML" select="/"/>
<xsl:template match="/">
<xsl:for-each select="$XML">
<xsl:for-each select="landxml:LandXML/hexagon:HexagonLandXML/hexagon:Point">
<xsl:for-each select="hexagon:PointCode">
<xsl:when test="../following-sibling::*[1]
/hexagon:PointCode[@codeLinework='none']
or
../../following-sibling::*[1]
/hexagon:Point[@lineworkFlag='START LINJE']">
do something...
</xsl:when>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:0)
欢迎使用Stack Overflow。
由于您没有提及任何错误消息的文本,我猜您没有收到任何错误。既然你问你是否可以做你的代码正在做的事情,我猜你没有得到你想要或期望的结果。既然我不完全确定你的意思是“在逻辑上用'或'在不同的路径中测试”或“以某种方式将它分开”,我必须对你的意思有点猜测。 (这是很多猜测;如果我的猜测有任何错误,这个答案将无济于事。)
我认为你最初想问的问题可能是这样的:当test
属性的顶级运算符是or
时,写or
的两个操作数是合法的吗? {1}}是对两个完全不同的元素的测试?或者必须限制单个test
属性中的测试,以便它们不会在输入中漫游?或者换句话说,这是合法的吗?
<xsl:when test="../following-sibling::*[1]
/hexagon:PointCode[@codeLinework='none']
or
../../following-sibling::*[1]
/hexagon:Point[@lineworkFlag='START LINJE']">
do something...
</xsl:when>
或必须重写为
<xsl:when test="../following-sibling::*[1]
/hexagon:PointCode[@codeLinework='none'] ">
do something...
</xsl:when>
<xsl:when test="../../following-sibling::*[1]
/hexagon:Point[@lineworkFlag='START LINJE']">
do the exact same something...
</xsl:when>
该问题(或:那些问题)的答案是:是的,test
可能有or
作为其顶级运营商;不,or
的两个操作数不需要相关,或者通过任何可定义的邻近度量来寻址彼此接近的元素。第一种形式(一个xsl:when
)很好,并且只要“做某事”变得复杂,就会优先考虑第二种形式(两个xsl:when
元素)。
如果我的猜测是正确的,那么你的代码合法的消息将消除你试图解决的任何问题的一个可能的解释,但留下问题“那为什么我没有得到我期望的输出?”由于您没有提供样本输入,其中这些关键代码将会触发,或者说明了您当前获得的所需输出和输出,因此这里的任何人都无法回答这个未提出的问题。
目前,很明显你基本上是用尖括号编写程序代码;你可能会发现,如果你努力获得一种更具说明性的风格,那么XSLT就会变得更容易使用(包括我在内的大多数人似乎都意味着使用xsl:apply-templates
提供的隐式循环而不是{{1}在模板上使用匹配模式,优先选择/何时使用)。或者你可能不会;不是每个人都这样做。
作为示例,这里是以不同的样式重写样式表:
xsl:for-each
如果您的输入与其建议的示例一样常规,那么您的条件可归结为“下一个PointCode元素具有@codeLinework ='none'或下一个Point元素具有@ lineworkFlag ='START LINJE'如果是这样,那么条件可以稍微缩短:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:landxml="http://www.landxml.org/schema/LandXML-1.2"
xmlns:hexagon="http://xml.hexagon.com/schema/HeXML-1.7"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"
version="1.0"
encoding="UTF-16"
indent="no"
omit-xml-declaration="yes"/>
<xsl:template match="hexagon:Point
[following-sibling::*[1]
/hexagon:PointCode
/@codeLinework = 'none']
/hexagon:PointCode">
<xsl:call-template name="do-something"/>
</xsl:template>
<!--* pattern on following template seems likely wrong *-->
<xsl:template match="hexagon:HexagonLandXML
[following-sibling::*[1]
/hexagon:Point
/@lineworkFlag = 'START LINJE']
//hexagon:PointCode">
<xsl:call-template name="do-something"/>
</xsl:template>
<xsl:template name="do-something">
do something ...
</xsl:template>
</xsl:stylesheet>
条件的复杂性可能会向某些读者(对我而言)表明XML的设计可能会被有效地改变以允许更直接的处理。但这超出了你的问题的范围。