0

我是 xml、xsl 和 xPath 的初学者。我想知道如何检查我所有的 refid 属性是否有效?

换句话说,如果每个 refid 属性都有一个匹配的 ID 属性(当然具有相同的值),我希望有一个返回 TRUE 的 xPath 1.0 查询。所有产品都不需要有 ref 节点。

例如:如果 cookie 指向面包,面包指向牛奶,牛奶指向 cookie,则返回 TRUE,否则返回 FALSE。

我一直在尝试解决这个问题,并在网上搜索了一个没有运气的好例子。帮助将不胜感激!

这是我的 XML:

<shop>
 <product>
    <cookie ID="01">
    <price>2</price>
    </cookie>
    <ref refid="02"/>
 </product>

  <product>
    <bread ID="02">
    <price>5</price>
    </bread>
    <ref refid="03"/>
 </product>

 <product>
   <milk ID="03">
   <price>2</price>
   </milk>
   <ref refid="01"/>
</product>

</shop>
4

3 回答 3

1

随着问题被标记xslt以及xpath我敢于建议使用密钥的 XSLT 1.0 方法:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

<xsl:key name="id" match="product" use="*[1]/@ID"/>

<xsl:template match="/">
  <xsl:choose>
    <xsl:when test="//ref[not(key('id', @refid))]">FALSE</xsl:when>
    <xsl:otherwise>TRUE</xsl:otherwise>
  </xsl:choose>
</xsl:template>

</xsl:stylesheet>
于 2013-02-15T14:46:25.317 回答
1

你可以使用boolean(). 以下将返回trueor false

boolean(not(//@refid[not(.=//@ID)]))

XSLT 示例:

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

    <xsl:template match="/">
        <xsl:value-of select="boolean(not(//@refid[not(.=//@ID)]))"/>
    </xsl:template>

</xsl:stylesheet>

boolean()也可以用于 Martin 更高效的xsl:key版本:

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

    <xsl:key name="id" match="product" use="*[1]/@ID"/>

    <xsl:template match="/">
        <xsl:value-of select="boolean(not(//ref[not(key('id', @refid))]))"/>
    </xsl:template>

</xsl:stylesheet>
于 2013-02-15T15:53:50.597 回答
0

查找所有@refid不匹配的属性@id

//@refid[not(//@ID = .)]

如果您计算结果并将其与零进行比较,它将返回true有效输入和false损坏的引用。

count(//@refid[not(//@ID = .)]) = 0
于 2013-02-15T15:01:41.633 回答