如何使用 Exslt - set:distinct 解决 XML 到 XML 问题

发布于 2024-08-19 08:20:53 字数 2064 浏览 11 评论 0原文

这从 XML to XML using XSL Problem 延伸而来 我设法导入 exslt 并根据给出的解决方案(感谢 Kyle Butt)修改了我的代码,如下所示:

<xsl:stylesheet version="1.0"
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
              xmlns:func="http://exslt.org/functions"
              xmlns:set="http://exslt.org/sets"
              extension-element-prefixes="set">

<xsl:import href="set.distinct.function.xsl"/>

<xsl:output method="xml" indent="yes"/>

<xsl:template match="gallery">
  <gallery>
    <xsl:variable name="gallery" select="."/>
    <xsl:for-each select="set:distinct(photo/tag/event)">
      <xsl:value-of select="."/>
      <event name="{.}">
        <xsl:variable name="event" select="." />
        <xsl:for-each select="set:distinct($gallery/object/tag[event=.]/group)">
          <group name="{.}">
            <xsl:variable name="group" select="." />
            <xsl:apply-templates select="$gallery/object[tag/event=$event][tag/group=$group]" />
          </group>
        </xsl:for-each>
      </event>
    </xsl:for-each>
  </gallery>
</xsl:template>

但输出中出现错误,显示“函数集:distinct() 失败。”值不能为空。'怎么解决这个问题呢?

顺便说一句,XML 输入:

<gallery>
  <photo>
    <tag>
      <event>Birthday</event>
      <group>Family</group>
      <other>Swensens</other>
    </tag>
  </photo>
  <photo>..</photo>
</gallery>

&所需的 XML 输出:

<gallery>
  <event name="Birthday">
    <group name="Family">
      <photo>
        <tag>
         <other>Swensens</other>
        </tag>
      </photo>
      <photo>..</photo>
    </group>
    <group>..</group>
  </event>
  <event>..</event>
</gallery>

This extends from XML to XML using XSL Problem
I managed to import exslt and modified my codes according to the solution (thanks to Kyle Butt) given as follows:

<xsl:stylesheet version="1.0"
              xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
              xmlns:func="http://exslt.org/functions"
              xmlns:set="http://exslt.org/sets"
              extension-element-prefixes="set">

<xsl:import href="set.distinct.function.xsl"/>

<xsl:output method="xml" indent="yes"/>

<xsl:template match="gallery">
  <gallery>
    <xsl:variable name="gallery" select="."/>
    <xsl:for-each select="set:distinct(photo/tag/event)">
      <xsl:value-of select="."/>
      <event name="{.}">
        <xsl:variable name="event" select="." />
        <xsl:for-each select="set:distinct($gallery/object/tag[event=.]/group)">
          <group name="{.}">
            <xsl:variable name="group" select="." />
            <xsl:apply-templates select="$gallery/object[tag/event=$event][tag/group=$group]" />
          </group>
        </xsl:for-each>
      </event>
    </xsl:for-each>
  </gallery>
</xsl:template>

But theres error in the output which says- 'Function set:distinct() has failed. Value Cannot be null.' How to solve this?

Btw The XML input:

<gallery>
  <photo>
    <tag>
      <event>Birthday</event>
      <group>Family</group>
      <other>Swensens</other>
    </tag>
  </photo>
  <photo>..</photo>
</gallery>

& Required XML output:

<gallery>
  <event name="Birthday">
    <group name="Family">
      <photo>
        <tag>
         <other>Swensens</other>
        </tag>
      </photo>
      <photo>..</photo>
    </group>
    <group>..</group>
  </event>
  <event>..</event>
</gallery>

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

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

发布评论

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

评论(1

鹤舞 2024-08-26 08:20:53

当我按原样在输入上运行 XSL 时,我没有收到错误,但这是我得到的输出:

<gallery>
  Birthday
  <event name="Birthday"/>
</gallery>

因此,这里发生的许多事情无法让您获得所需的输出。一件事是,您只是将事件名称输出为库节点的值,因此要摆脱它,您需要删除>在第一个 xsl:for-each 中(也许是留下了这个调试代码?)

然后查看 xsl:for-each 中事件的这一部分:

<xsl:variable name="event" select="." />
<xsl:for-each select="set:distinct($gallery/object/tag[event=.]/group)">

我发现 set:distinct 中的 XPath 存在一些问题:

  1. 您提供的 XML 输入中图库节点下方的节点是,在您的 XPath 中您有“object”。
  2. 您没有使用 $event 变量来检查事件节点 - 标记上的谓词应该是 [event=$event]。

这些是导致您看到的错误的原因 - XPath 没有选择任何内容,因此您在 null 上调用 set:distinct。

因此,进行这些更正后,我得到的输出是:

<gallery>
  <event name="Birthday">
    <group name="Family"/>
  </event>
</gallery>

然后中的 XPath还需要将对象更改为照片。在我的样式表中,我添加了一个与照片匹配的模板,因为它没有包含在您的示例样式表中,所以我的样式表现在看起来像:

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:func="http://exslt.org/functions"
          xmlns:set="http://exslt.org/sets"
          extension-element-prefixes="set">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="gallery">
  <gallery>
    <xsl:variable name="gallery" select="."/>
    <xsl:for-each select="set:distinct(photo/tag/event)">
      <event name="{.}">
        <xsl:variable name="event" select="." />
        <xsl:for-each select="set:distinct($gallery/photo/tag[event=$event]/group)">
          <group name="{.}">
            <xsl:variable name="group" select="." />
            <xsl:apply-templates select="$gallery/photo[tag/event=$event][tag/group=$group]" />
          </group>
        </xsl:for-each>
      </event>
    </xsl:for-each>
  </gallery>
</xsl:template>

<xsl:template match="photo">
  <photo>
    <tag>
      <xsl:copy-of select="tag/*[not(name(.)='group') and not(name(.)='event')]" />
    </tag>
  </photo>
</xsl:template>
</xsl:stylesheet>

我得到的输出是:

<gallery>
  <event name="Birthday">
    <group name="Family">
      <photo>
        <tag>
          <other>Swensens</other>
        </tag>
      </photo>
    </group>
  </event>
</gallery>

Tada!

When I run your XSL on your input as-is, I'm not getting an error, but this is the output I get:

<gallery>
  Birthday
  <event name="Birthday"/>
</gallery>

So there are a number of things going on here that aren't getting you to the output that you want. One thing is that you're just outputting the name of the event as the gallery node's value, so to get rid of that you'll want to remove the <xsl:value-of select="." /> within the first xsl:for-each (was this debugging code left in, perhaps?)

Then looking at this part within the xsl:for-each on the events:

<xsl:variable name="event" select="." />
<xsl:for-each select="set:distinct($gallery/object/tag[event=.]/group)">

I'm seeing a few issues with the XPath within the set:distinct:

  1. The node beneath the gallery node in the XML input you gave is <photo>, and in your XPath you have "object".
  2. You're not using the $event variable to check the event node-- the predicate on tag should be [event=$event].

These are what's contributing to the error you're seeing-- the XPath isn't selecting anything so you're calling set:distinct on null.

So making these corrections, the output I get is:

<gallery>
  <event name="Birthday">
    <group name="Family"/>
  </event>
</gallery>

Then the XPath in <xsl:apply-templates select="$gallery/object[tag/event=$event][tag/group=$group]" /> needs to have object changed to photo as well. In my stylesheet I added a template that matches photo since it wasn't included in your sample stylesheet, so my stylesheet now looks like:

<xsl:stylesheet version="1.0"
          xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
          xmlns:func="http://exslt.org/functions"
          xmlns:set="http://exslt.org/sets"
          extension-element-prefixes="set">
<xsl:output method="xml" indent="yes"/>

<xsl:template match="gallery">
  <gallery>
    <xsl:variable name="gallery" select="."/>
    <xsl:for-each select="set:distinct(photo/tag/event)">
      <event name="{.}">
        <xsl:variable name="event" select="." />
        <xsl:for-each select="set:distinct($gallery/photo/tag[event=$event]/group)">
          <group name="{.}">
            <xsl:variable name="group" select="." />
            <xsl:apply-templates select="$gallery/photo[tag/event=$event][tag/group=$group]" />
          </group>
        </xsl:for-each>
      </event>
    </xsl:for-each>
  </gallery>
</xsl:template>

<xsl:template match="photo">
  <photo>
    <tag>
      <xsl:copy-of select="tag/*[not(name(.)='group') and not(name(.)='event')]" />
    </tag>
  </photo>
</xsl:template>
</xsl:stylesheet>

and the output I get is:

<gallery>
  <event name="Birthday">
    <group name="Family">
      <photo>
        <tag>
          <other>Swensens</other>
        </tag>
      </photo>
    </group>
  </event>
</gallery>

Tada!!

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