Xml XSLT-用于组合两个函数的内部联接类型命令

Xml XSLT-用于组合两个函数的内部联接类型命令,xml,xslt,Xml,Xslt,我有两个输出XML数据的函数。理想情况下,我希望将每个函数的输出组合成一个变量来解析数据 在SQL术语中,每个函数都可以通过属性PageId通过内部连接连接在一起。。。但是XSLT中不允许连接(至少据我所知) 关于组合这些功能的最干净/最简单的方法有何建议?我调用的函数内置于cms中,无法编辑 更多信息: 第一个功能是站点地图。它列出了网站的网页ID及其级别 第二个函数提取我需要与站点地图结合的网页ID及其元数据标记 我曾考虑过为第二个函数页面ID创建变量,但带有元数据标记的页面数量会发生变化,

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

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

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

更多信息:

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

第二个函数提取我需要与站点地图结合的网页ID及其元数据标记

我曾考虑过为第二个函数页面ID创建变量,但带有元数据标记的页面数量会发生变化,我认为这些变量不支持动态名称

如果我不够清楚,我很抱歉,因为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属性附加到站点地图。

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


问题的详细答案取决于您使用的是XSLT1.0还是2.0,以及要组合的函数是传递XML值还是传递原子值。用具体的示例输入和输出提出具体的问题确实更有效,这样我们就可以给出具体的答案。

此转换

<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>
<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>

应用于提供的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>

生成所需的正确结果

<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>
<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>

说明

<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>
<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>
  • 按“原样”复制选择执行此模板的每个节点

  • 有两个覆盖模板,其中第二个模板的正文为空,即在:result中第二次出现的

  • 第一个覆盖模板匹配任何
    页面
    ,该页面是在:result
    中第一次出现的
    的子页面。我们使用键高效方便地在其
    PageId
    属性中找到引用当前
    Page
    isroot
    元素,并复制其
    isroot
    属性


  • 您可以使用XSLT2.0,还是仅限于1.0?2.0中有一些功能可以使任务变得更简单。result
    中的两个
    元素是否真的嵌套了,或者这是您的代码示例中的一个输入错误?第二个
    页面
    元素在哪里关闭?我们将使用XSLT1.0。这些函数正在传递XML数据。我很少使用SQL,很少使用XSLT函数,所以如果我不清楚,我很抱歉。我已经在我的原始请求中添加了一些代码。非常好!谢谢我不熟悉身份规则或使用密钥,但我会通过谷歌搜索这些术语来充分了解函数是如何工作的。非常感谢@用户673869:不客气。在我的回答中,有这两种技术的链接——特别是XSLT FAQ是有关XSLT问题解决方法的最佳资源之一。