简体   繁体   English

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

[英]How to solve XML to XML problem using Exslt - set:distinct

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: 是使用XSLXML扩展到XML的问题。我设法导入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>

But theres error in the output which says- 'Function set:distinct() has failed. 但是输出中显示错误-'功能set:distinct()失败。 Value Cannot be null.' 值不能为空。 How to solve this? 如何解决呢?

Btw The XML input: Btw XML输入:

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

& Required XML output: &必需的XML输出:

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

When I run your XSL on your input as-is, I'm not getting an error, but this is the output I get: 当我按原样在输入上运行XSL时,我没有收到错误,但这是我得到的输出:

<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="." 一件事是,您只是将事件的名称作为图库节点的值输出,因此要消除该事件,您需要删除<xsl:value-of select =“。 /> within the first xsl:for-each (was this debugging code left in, perhaps?) 在第一个xsl:for-each中(也许是否保留了此调试代码?)

Then looking at this part within the xsl:for-each on the events: 然后在xsl:for-each事件中查看此部分:

<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: 我在set:distinct中看到了XPath的一些问题:

  1. The node beneath the gallery node in the XML input you gave is <photo>, and in your XPath you have "object". 在您输入的XML输入中,Gallery节点下的节点是<photo>,在XPath中您拥有“对象”。
  2. You're not using the $event variable to check the event node-- the predicate on tag should be [event=$event]. 您没有使用$ event变量检查事件节点-标记上的谓词应为[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. 这些是导致您看到的错误的原因-XPath没有选择任何内容,因此您在null上调用set:distinct。

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. 然后,<xsl:apply-templates select =“ $ gallery / object [tag / event = $ event] [tag / group = $ group]” />中的XPath也需要将对象更改为照片。 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!! 多田!!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM