gpt4 book ai didi

xslt - 在XPATH/XSL中使用“except”时的结构要求

转载 作者:行者123 更新时间:2023-12-03 16:40:16 27 4
gpt4 key购买 nike

我在xpath中使用“ except”时遇到麻烦。这是问题代码的一部分。 (我试图尽可能简化而不掩盖整个问题):

<!--First, create a variable containing some nodes that we want to filter out. 
(I'm gathering elements that are missing child VALUE elements
and whose child DOMAIN and VARIABLE elements only occur once
in the parent list of elements.)
I've confirmed that this part does generate the nodes I want,
but maybe this is the incorrect result structure?-->

<xsl:variable name="badValues">
<xsl:for-each select="$root/A[not(VALUE)]">
<xsl:choose>
<xsl:when test="count($root/A[DOMAIN=current()/DOMAIN and VARIABLE=current()/VARIABLE])=1">
<xsl:copy-of select="."/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:variable>

<!--Next Loop over the original nodes, minus those bad nodes.
For some reason, this loops over all nodes and does not filter out the bad nodes.-->

<xsl:for-each select="$root/A except $badValues/A"> ...

最佳答案

在不使用xsl:variable的情况下创建@select并且不使用@as指定类型时,它将创建变量为temporary tree

您想创建一个节点序列,以便在except运算符中对它们进行比较时,会将它们“视为”相同的节点。您可以通过为as="node()*"指定xsl:variable并使用xsl:sequence代替xsl:copy-of来做到这一点:

<xsl:variable name="badValues" as="node()*">
<xsl:for-each select="$root/A[not(VALUE)]">
<xsl:choose>
<xsl:when test="count($root/A[DOMAIN=current()/DOMAIN
and VARIABLE=current()/VARIABLE])=1">
<xsl:sequence select="."/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:variable>




另外,如果您要使用 @select并消除 xsl:for-each,它也将起作用。按照 Martin Honnen的建议,您可以使用 xsl:key并选择以下值:

 <xsl:key name="by-dom-and-var" match="A" use="concat(DOMAIN, '|', VARIABLE)"/>


然后将您的badValues更改为此:

<xsl:variable name="badValues" 
select="$root/A[not(VALUE)]
[count(key('by-dom-and-var',
concat(DOMAIN, '|', VARIABLE))/VARIABLE) = 1]"/>>




通过执行以下样式表在项目上进行迭代时,可以使用 generate-id()函数来查看节点身份的差异:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>

<xsl:template match="/">
<xsl:variable name="root" select="*" as="item()*"/>
<xsl:variable name="originalBadValues">
<xsl:for-each select="$root/A[not(VALUE)]">
<xsl:choose>
<xsl:when test="count($root/A[DOMAIN=current()/DOMAIN
and VARIABLE=current()/VARIABLE])=1">
<xsl:copy-of select="."/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:variable>

<xsl:variable name="badValues" as="node()*">
<xsl:for-each select="$root/A[not(VALUE)]">
<xsl:choose>
<xsl:when test="count($root/A[DOMAIN=current()/DOMAIN
and VARIABLE=current()/VARIABLE])=1">
<xsl:sequence select="."/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:variable>

<!--These are the generated ID values of all the A elements-->
<rootA>
<xsl:value-of select="$root/A/generate-id()"
separator=", "/>
</rootA>
<!--These are the generated ID values for
the original $badValues/A -->
<originalBadValues>
<xsl:value-of select="$originalBadValues/A/generate-id()"
separator=", " />
</originalBadValues>
<!--These are the generated ID values for
the correct selection of $badValues-->
<badValues>
<xsl:value-of select="$badValues/generate-id()"
separator=", " />
</badValues>
<!--The generated ID values for the result of
the except operator filter-->
<final>
<xsl:value-of select="($root/A except $badValues)/generate-id()"
separator=", "/>
</final>
</xsl:template>
</xsl:stylesheet>


针对此XML文件执行:

<doc>
<A>
<VALUE>skip me</VALUE>
<DOMAIN>a</DOMAIN>
<VARIABLE>a</VARIABLE>
</A>
<A>
<DOMAIN>a</DOMAIN>
<VARIABLE>a</VARIABLE>
</A>
<A>
<DOMAIN>b</DOMAIN>
<VARIABLE>b</VARIABLE>
</A>
<A>
<DOMAIN>c</DOMAIN>
<VARIABLE>c</VARIABLE>
</A>
<A>
<DOMAIN>a</DOMAIN>
<VARIABLE>a</VARIABLE>
</A>
</doc>


它产生以下输出:

<rootA>d1e3, d1e15, d1e24, d1e33, d1e42</rootA>
<originalBadValues>d2e1, d2e9</originalBadValues>
<badValues>d1e24, d1e33</badValues>
<final>d1e3, d1e15, d1e42</final>

关于xslt - 在XPATH/XSL中使用“except”时的结构要求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16738391/

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