gpt4 book ai didi

xslt - XPath/XSLT 嵌套谓词 : how to get the context of outer predicate?

转载 作者:行者123 更新时间:2023-12-03 15:22:55 25 4
gpt4 key购买 nike

这个问题之前好像没有在stackoverflow上讨论过,除了Working With Nested XPath Predicates ... Refined其中提供了不涉及嵌套谓词的解决方案。

所以我试图写出我想要得到的过于简化的样本:

输入:

<root>
<shortOfSupply>
<food animal="doggie"/>
<food animal="horse"/>
</shortOfSupply>
<animalsDictionary>
<cage name="A" animal="kittie"/>
<cage name="B" animal="dog"/>
<cage name="C" animal="cow"/>
<cage name="D" animal="zebra"/>
</animals>
</root>

输出:
<root>
<hungryAnimals>
<cage name="B"/>
<cage name="D"/>
</hungryAnimals>
</root>

或者,如果没有交叉点,
<root>
<everythingIsFine/>
</root>

我想使用嵌套谓词来获取它:
<xsl:template match="cage">
<cage>
<xsl:attribute name="name">
<xsl:value-of select="@name"/>
</xsl:attribute>
</cage>
</xsl:template>

<xsl:template match="/root/animalsDictionary">
<xsl:choose>
<!-- in <food> in <cage> -->
<xsl:when test="cage[/root/shortOfSupply/food[ext:isEqualAnimals(./@animal, ?????/@animal)]]">
<hungryAnimals>
<xsl:apply-templates select="cage[/root/shortOfSupply/food[ext:isEqualAnimals(@animal, ?????/@animal)]]"/>
</hungryAnimals>
</xsl:when>
<xsl:otherwise>
<everythingIsFine/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

那么我应该写什么来代替 ????? ?

我知道我可以使用更多的模板和变量/参数的广泛使用来重写整个样式表,但它甚至使这个样式表变得更加复杂,更不用说我有真正问题的真正样式表了。

在 XPath 引用中写的是点 . sign 表示当前上下文节点,但不说明是否有可能在此之前获取上下文节点;我简直不敢相信 XPath 缺少这个明显的功能。

最佳答案

XPath 2.0 单行版 :

for $a in /*/animalsDictionary/cage
return
if(/*/shortOfSupply/*[my:isA($a/@animal, @animal)])
then $a
else ()

当应用于提供的 XML 文档时,选择 :
   <cage name="B"/>
<cage name="D"/>

不能使用单个 XPath 1.0 表达式来发现给定的笼子里有一只饥饿的动物。

这是一个 XSLT 解决方案 (XSLT 2.0 仅用于避免使用扩展函数进行比较——在 XSLT 1.0 解决方案中,将使用扩展函数进行比较,并使用 xxx:node-set() 扩展来测试是否通过在正文中应用模板生成的 RTF变量包含任何子元素):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:my="my:my" exclude-result-prefixes="xs my">
<xsl:output omit-xml-declaration="yes" indent="yes"/>

<my:Dict>
<a genName="doggie">
<name>dog</name>
<name>bulldog</name>
<name>puppy</name>
</a>
<a genName="horse">
<name>horse</name>
<name>zebra</name>
<name>pony</name>
</a>
<a genName="cat">
<name>kittie</name>
<name>kitten</name>
</a>
</my:Dict>

<xsl:variable name="vDict" select=
"document('')/*/my:Dict/a"/>

<xsl:template match="/">
<root>
<xsl:variable name="vhungryCages">
<xsl:apply-templates select=
"/*/animalsDictionary/cage"/>
</xsl:variable>

<xsl:choose>
<xsl:when test="$vhungryCages/*">
<hungryAnimals>
<xsl:copy-of select="$vhungryCages"/>
</hungryAnimals>
</xsl:when>
<xsl:otherwise>
<everythingIsFine/>
</xsl:otherwise>
</xsl:choose>
</root>
</xsl:template>

<xsl:template match="cage">
<xsl:if test="
/*/shortOfSupply/*[my:isA(current()/@animal,@animal)]">

<cage name="{@name}"/>
</xsl:if>
</xsl:template>

<xsl:function name="my:isA" as="xs:boolean">
<xsl:param name="pSpecName" as="xs:string"/>
<xsl:param name="pGenName" as="xs:string"/>

<xsl:sequence select=
"$pSpecName = $vDict[@genName = $pGenName]/name"/>
</xsl:function>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时 (更正为格式良好):
<root>
<shortOfSupply>
<food animal="doggie"/>
<food animal="horse"/>
</shortOfSupply>
<animalsDictionary>
<cage name="A" animal="kittie"/>
<cage name="B" animal="dogs"/>
<cage name="C" animal="cow"/>
<cage name="D" animal="zebras"/>
</animalsDictionary>
</root>

产生了想要的、正确的结果 :
<root>
<hungryAnimals>
<cage name="B"/>
<cage name="D"/>
</hungryAnimals>
</root>

说明 : 请注意 XSLT current() 的使用功能。

关于xslt - XPath/XSLT 嵌套谓词 : how to get the context of outer predicate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6595034/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com