繁体   English   中英

在xpath中设置节点

[英]node-set in xpath

我正在编写一个xslt样式表来将xml转换为另一个xml。

这是原始xml的简化版本:

 <eml>
        <datatable>
                 <physical>
                     <distribution id="100"/>
                 </physical>
       </datatable>                 

       <software>
           <implementation>
              <distribution id="200"/>
            </implementation>
      </software>
     <additionalMetadata>
        <describes>100</describes>
        <describes>200</describes>
        <describes>300</describes>
        <describes>400</describes>
    </additionalMetadata>
   </eml>

我尝试使用Xpath来选择“describe”的节点集,该节点集的值不等于//physical/distributionsoftware/implementation/distribution的id值。 在上面的例子中,我想得到节点集:

   <deseribes>300</describes>
   <deseribes>400</describes>

(100和200是//physical/distributionsoftware/implementation/distribution属性id值)。

我写了类似的东西:

<xsl:with-param name="describes-list" 
                select="./describes[//physical/distribution/@id !=. and
                             //software/implementation/distribution/@id != .] "/>

它适用于上面的例子。 但是,数据表和软件的元素是可重复的。 所以这个xml是有效的:

<eml>
    <datatable>
             <physical>
                 <distribution id="100"/>
             </physical>
   </datatable> 

  <datatable>
             <physical>
                 <distribution id="300"/>
             </physical>
   </datatable>                

   <software>
       <implementation>
          <distribution id="200"/>
       </implementation>
  </software>
 <additionalMetadata>
    <describes>100</describes>
    <describes>200</describes>
    <describes>300</describes>
    <describes>400</describes>
  </additionalMetadata>
</eml>

但我的xslt不适用于上面的例子:(

你介意对此有所了解吗? 先感谢您!

这是一个经常犯的错误。 当一个或两个操作数是节点集时,切勿使用XPath的“!=”运算符

value != node-set

根据定义,如果节点集中存在节点n,则为true

value不等于string(n)

你想要的是那个

value不等于node-set中的任何节点。

这可以用以下方式表达:

value = node-set

如果节点集中至少存在一个节点n,则为true,这样:

value = string(n)

然后

not(value = node-set)

如果节点集中不存在任何节点n,则为true

value = string(n)

因此,以下XPath表达式将选择所需的节点

/*/*/describes[not(. = ../../*/physical/distribution/@id)
              and 
                not(. = ../../*/implementation/distribution/@id)]

我个人更愿意只将上下文节点与两个节点集的并集进行一次比较:

/*/*/describes
            [not(. = (../../*/physical/distribution/@id
                    | 
                      ../../*/implementation/distribution/@id
                     )
                 )
            ]

请注意,我避免使用“//”缩写 它通常非常昂贵(效率低​​下),只有在我们不知道XML文档的结构时才应该使用它。

当然,上述XPath表达式必须针对以下XML文档进行评估(问题中提供的第二个):

<eml>
    <datatable>
        <physical>
            <distribution id="100"/>
        </physical>
    </datatable>
    <datatable>
        <physical>
            <distribution id="300"/>
        </physical>
    </datatable>
    <software>
        <implementation>
            <distribution id="200"/>
        </implementation>
    </software>
    <additionalMetadata>
        <describes>100</describes>
        <describes>200</describes>
        <describes>300</describes>
        <describes>400</describes>
    </additionalMetadata>
</eml>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM