独立于深度计算 XSLT 中的不同项目

发布于 2024-09-09 06:28:42 字数 2523 浏览 1 评论 0原文

运行以下 XSLT 代码:

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

 <xsl:key name="kValueByVal" match="variable_name/@value"
  use="."/>

 <xsl:template match="assessment">
  <xsl:for-each select="
   /*/*/variable/attributes/variable_name/@value
             [generate-id()
             =
              generate-id(key('kValueByVal', .)[1])
             ]
   ">
     <xsl:value-of select=
     "concat(., ' ', count(key('kValueByVal', .)), '&#xA;')"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

如果我在以下 XML 上

<assessment>
    <variables>
        <variable>
            <attributes>
                <variable_name value="FRED"/>
            </attributes>
        </variable>
    </variables>
    <variables>
        <variable>
            <attributes>
                <variable_name value="MORTIMER"/>
            </attributes>
        </variable>
    </variables>
    <variables>
        <variable>
            <attributes>
                <variable_name value="FRED"/>
            </attributes>
        </variable>
    </variables>
</assessment>

我会得到所需的输出:(

FRED 2
MORTIMER 1

请参阅 我的如果您愿意,请原始问题了解更多信息。)

但是,如果我在此输入上运行它:

<ExamStore>
    <assessment>
        <variables>
            <variable>
                <attributes>
                    <variable_name value="FRED"/>
                </attributes>
            </variable>
        </variables>
        <variables>
            <variable>
                <attributes>
                    <variable_name value="MORTIMER"/>
                </attributes>
            </variable>
        </variables>
        <variables>
            <variable>
                <attributes>
                    <variable_name value="FRED"/>
                </attributes>
            </variable>
        </variables>
    </assessment>
</ExamStore>

我什么也得不到。 (请注意,我只是将原始输入包装在 ExamStore 标签中。)我期待并希望得到相同的输出。

我为什么不呢?如何更改原始 XSLT 代码以获得相同的输出?

If I run the following XSLT code:

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

 <xsl:key name="kValueByVal" match="variable_name/@value"
  use="."/>

 <xsl:template match="assessment">
  <xsl:for-each select="
   /*/*/variable/attributes/variable_name/@value
             [generate-id()
             =
              generate-id(key('kValueByVal', .)[1])
             ]
   ">
     <xsl:value-of select=
     "concat(., ' ', count(key('kValueByVal', .)), '
')"/>
  </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

on the following XML:

<assessment>
    <variables>
        <variable>
            <attributes>
                <variable_name value="FRED"/>
            </attributes>
        </variable>
    </variables>
    <variables>
        <variable>
            <attributes>
                <variable_name value="MORTIMER"/>
            </attributes>
        </variable>
    </variables>
    <variables>
        <variable>
            <attributes>
                <variable_name value="FRED"/>
            </attributes>
        </variable>
    </variables>
</assessment>

I get the desired output:

FRED 2
MORTIMER 1

(See my original question for more info, if you wish.)

However, if I run it on this input:

<ExamStore>
    <assessment>
        <variables>
            <variable>
                <attributes>
                    <variable_name value="FRED"/>
                </attributes>
            </variable>
        </variables>
        <variables>
            <variable>
                <attributes>
                    <variable_name value="MORTIMER"/>
                </attributes>
            </variable>
        </variables>
        <variables>
            <variable>
                <attributes>
                    <variable_name value="FRED"/>
                </attributes>
            </variable>
        </variables>
    </assessment>
</ExamStore>

I get nothing. (Note that I just wrapped the original input in an ExamStore tag.) I was expecting and hoping to get the same output.

Why don't I? How can I change the original XSLT code to get the same output?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你不是我要的菜∠ 2024-09-16 06:28:42

那么您选择的 xpath /*/*/variable/attributes/variable_name/... 不再正确,因为您在节点树中添加了另一个更高的节点。

如果你想拥有真正的独立性,你需要使用类似的东西:

//variable/attributes/variable_name/...

...(不是开头的双斜杠),但这相当危险,因为它会捕获该结构的所有出现 - 真正确定这就是你的意思。

否则,只需在 xpath 前面加上另一个 /*

Well your select xpath /*/*/variable/attributes/variable_name/... is no longer correct because you added another node higher in the node-tree.

If you want to have true independence you need to use something like:

//variable/attributes/variable_name/...

...(not the double slash at the start) but this is fairly dangerous because it will catch all occurences of that structure - be really sure that's what you mean.

Otherwise, just prepend your xpath with another /*

摇划花蜜的午后 2024-09-16 06:28:42

当您在 XML 文档中引入另一个级别时,这会搞砸原始解决方案中使用的绝对 XPath 表达式(完全按照原始 XML 文件命名)。

因此,为了使 XPath 表达式在新情况下工作,只需执行以下操作:

替换

/*/*/variable/attributes/variable_name/@value 

with

/*/*/*/variable/attributes/variable_name/@value

,现在您再次获得想要的整洁结果:

FRED 2
MORTIMER 1

我永远不会为您提供一个“独立”的解决方案,因为您没有提供有关您想要应用转换的可能 XML 文档集的任何属性/保证/约束。

在您最初的问题中,您使用了:

.//variables/variable/attributes/variable_name

关闭评估,

这就是我在解决方案中使用绝对 XPath 表达式的原因。无法保证在另一个 XML 文档中某些 variable_name 元素不会存在,因此它们的祖先链不是 variables/variable/attributes,如果是这种情况,这意味着您可能对此类“不规则”variable_name 元素的值不感兴趣。

教训是,人们不应该在定义问题时过于具体,然后想要通用的解决方案。 :)

When you introduced yet another level in the XML document, this screwed up the absolute XPath expression used in the original solution (taylored exactly after your original XML file).

Therefore, in order to make the XPath expression work in the new situation, just do the following:

Replace:

/*/*/variable/attributes/variable_name/@value 

with

/*/*/*/variable/attributes/variable_name/@value

and now you again get the wanted neat result:

FRED 2
MORTIMER 1

I would never give you an "independent" solution, because you haven't provided any properties/guarantees/constraints about the set of possible XML documents on which you want to apply the transformation.

In your original question you used:

.//variables/variable/attributes/variable_name

off assessment,

and this is why I used the absolute XPath expression in my solution. There was no guarantee that in another XML document some variable_name elements wouldn't exist such that their chain of ancestors is not variables/variable/attributes, If this were the case, this would mean that you probably were not interested in the values of such "irregular" variable_name elements.

The lesson is that one should not be too specific in defining a question and then want general solutions. :)

等数载,海棠开 2024-09-16 06:28:42

对于真正的结构独立性,您应该使用:

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

 <xsl:key name="kValueByVal" match="variable_name/@value"
  use="."/>

 <xsl:template match="variable_name[@value
             [generate-id()
             =
              generate-id(key('kValueByVal', .)[1])
             ]]">
     <xsl:value-of select=
     "concat(@value, ' ', count(key('kValueByVal', @value)), '
')"/>
 </xsl:template>
</xsl:stylesheet>

第一个输入的结果:

FRED 2
MORTIMER 1

第二个输入的结果:

FRED 2
MORTIMER 1

注意:切勿使用 // 作为第一个 XPath 运算符。

For real structure independence you should use:

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

 <xsl:key name="kValueByVal" match="variable_name/@value"
  use="."/>

 <xsl:template match="variable_name[@value
             [generate-id()
             =
              generate-id(key('kValueByVal', .)[1])
             ]]">
     <xsl:value-of select=
     "concat(@value, ' ', count(key('kValueByVal', @value)), '
')"/>
 </xsl:template>
</xsl:stylesheet>

Result with first input:

FRED 2
MORTIMER 1

Result with second input:

FRED 2
MORTIMER 1

Note: Never use // as fisrt XPath operator.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文