3

我有两个输出 XML 数据的函数。理想情况下,我想将每个函数的输出组合成一个变量来解析数据。

在 SQL 术语中,每个函数都可以通过属性 PageId... 通过内部连接连接在一起,但在 XSLT 中不允许连接(或者至少据我所知)。

关于组合这些功能的最干净/最简单的方法有什么建议吗?我调用的函数是内置在 cms 中的,无法编辑。

更多信息:

第一个功能是站点地图。它列出了网站的网页 ID 及其级别。

第二个函数将我需要的网页 ID 及其元数据标签与站点地图结合起来。

我考虑为第二个函数 Page Ids 创建变量,但是带有元数据标签的页面数量发生了变化,我不相信这些变量支持动态名称。

如果我不够清楚,我很抱歉,因为 xslt 对我来说是新的。如果需要更多信息,请告诉我。

编辑:添加代码示例

<in:inputs xmlns:in="http://www.composite.net/ns/transformation/input/1.0">
  <in:result name="SitemapXml">
    <Page Id="a0a47ce1-6eba-4d29-a7a3-3749c768c7e7" isopen="true" xmlns="">
      <Page Id="a3055286-0e90-4b04-99dd-fb1a61dde0bf" isopen='true' xmlns="">
        <Page Id="da675b13-d4d3-42ab-acc1-82e2a5408100" isopen='true' iscurrent='true' Depth="2"/>
      </Page>
    </Page>
  </in:result>
  <in:result name="GetisrootXml">
    <isroot PageId="a0a47ce1-6eba-4d29-a7a3-3749c768c7e7" Id="f8d4eea4-7070-4bc3-a804-e106697ffaa9" isroot="true" xmlns=""/>
    <isroot PageId="f8e4adbc-2758-42d6-bc40-0192ba0107a6" Id="db62e132-3f3b-493f-917a-9e090f887f13" isroot="false" xmlns=""/>
  </in:result>
</in:inputs>

我想要返回的内容:

<in:inputs xmlns:in="http://www.composite.net/ns/transformation/input/1.0">
  <in:result name="SitemapXml">
    <Page Id="a0a47ce1-6eba-4d29-a7a3-3749c768c7e7" isopen="true" xmlns="" isroot='true'>
    </Page>
    <Page Id="a3055286-0e90-4b04-99dd-fb1a61dde0bf" isopen='true' xmlns="">
        <Page Id="da675b13-d4d3-42ab-acc1-82e2a5408100" isopen='true' iscurrent='true' Depth="2"/>
  </in:result>
</in:inputs>

由此,我想进一步更改输出以满足我的需要(添加标签以供显示)。为了达到这一点,需要将 isroot 属性附加到站点地图。

4

2 回答 2

2

这种转变

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:in="http://www.composite.net/ns/transformation/input/1.0">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kIsRootByPageId" match="isroot" use="@PageId"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="in:result[1]/Page">
  <xsl:copy>
   <xsl:apply-templates select="@*"/>
   <xsl:copy-of select="key('kIsRootByPageId',@Id )/@isroot"/>
   <xsl:apply-templates select="node()"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="in:result[2]"/>
</xsl:stylesheet>

应用于提供的 XML 文档时:

<in:inputs xmlns:in="http://www.composite.net/ns/transformation/input/1.0">
    <in:result name="SitemapXml">
        <Page Id="a0a47ce1-6eba-4d29-a7a3-3749c768c7e7" isopen="true" xmlns=""></Page>
        <Page Id="a3055286-0e90-4b04-99dd-fb1a61dde0bf" isopen='true' xmlns="">
            <Page Id="da675b13-d4d3-42ab-acc1-82e2a5408100" isopen='true' iscurrent='true' Depth="2"/></Page>
    </in:result>
    <in:result name="GetisrootXml">
        <isroot PageId="a0a47ce1-6eba-4d29-a7a3-3749c768c7e7" Id="f8d4eea4-7070-4bc3-a804-e106697ffaa9" isroot="true" xmlns=""/>
        <isroot PageId="f8e4adbc-2758-42d6-bc40-0192ba0107a6" Id="db62e132-3f3b-493f-917a-9e090f887f13" isroot="false" xmlns=""/>
    </in:result>
</in:inputs>

产生想要的正确结果

<in:inputs xmlns:in="http://www.composite.net/ns/transformation/input/1.0">
   <in:result name="SitemapXml">
      <Page Id="a0a47ce1-6eba-4d29-a7a3-3749c768c7e7" isopen="true" isroot="true"/>
      <Page Id="a3055286-0e90-4b04-99dd-fb1a61dde0bf" isopen="true">
         <Page Id="da675b13-d4d3-42ab-acc1-82e2a5408100" isopen="true" iscurrent="true"
               Depth="2"/>
      </Page>
   </in:result>
</in:inputs>

说明

  1. 身份规则“按原样”复制选择此模板执行的每个节点。

  2. 有两个压倒一切的模板,第二个模板用它的空主体“删除”第二次出现的in:result.

  3. 第一个覆盖模板匹配任何Page第一次出现的in:result. 我们使用键来高效方便地找到在其属性isroot中引用当前元素的元素——并且我们复制它的属性。PagePageIdisroot

于 2012-07-09T12:33:26.940 回答
1

很难从用 SQL 术语表达的解决方案的描述中重建您的需求,因为我已经有很多年没有愤怒地使用 SQL 了。而且 XSLT 与 SQL 不同,因为它使用分层数据模型而不是表格数据模型,这意味着像“内连接”这样的术语不会直接映射。但是,当然可以在 XSLT 中进行连接(内部和外部):您通常将它们编写为嵌套循环。

您的问题的详细答案取决于您使用的是 XSLT 1.0 还是 2.0,以及要组合的函数是交付 XML 值还是原子值。用具体的例子输入输出来问具体的问题确实更有效,这样我们才能给出具体的答案。

于 2012-07-09T07:35:26.220 回答