【问题标题】:Analyzing tree/structure of XML (tags referencing eachother)分析 XML 的树/结构(标签相互引用)
【发布时间】:2012-08-13 12:41:29
【问题描述】:

我得到了几个使用“父”子元素相互引用的 XML 元素。并非所有顶级元素都需要复制,因此我有一个需要复制的(主)部分唯一名称的固定列表。

应该在我的 XSL 中复制哪些小节的主要部分列表:

<xsl:variable name="mainSections">|news|sport|</xsl:variable>

源 XML 主要部分:

<section uniqueName="news">
</section>

<section uniqueName="sport">
</section>

<section uniqueName="travel">
</section>

源 XML 子部分:

<section uniqueName="national_news">
  <parent uniqueName="news"/>
</section>

<section uniqueName="regional_news">
  <parent uniqueName="national_news"/>
</section>

<section uniqueName="city_news">
  <parent uniqueName="regional_news"/>
</section>

<section uniqueName="travel_europe">
  <parent uniqueName="travel"/>
</section>

<section uniqueName="holland">
  <parent uniqueName="travel_europe"/>
</section>

等等

由于子部分很容易在 XSL 的开发阶段和生产阶段之间移动、更改或删除,因此我需要动态确定任何给定的子部分是否是主要部分之一的子部分。总共还有无数的小节。硬编码要复制的小节列表是不可撤销的。

小节深度可以很深,如示例所示:节“city_news”以“regional_news”为父级,以“national_news”为父级,以“news”为父级,因此该节需要复制,因为它最终是“新闻”的孩子。 “holland”部分的顶层部分“Travel”(在“travel_europe”小节下)不在要复制的列表中,因此需要忽略。

起初我尝试检查每个元素是否父元素在列表中,但这太愚蠢了,它只会让我深入 1 级。 我的最后一次尝试是创建一个 javascript,首先索引所有部分,然后分析结构,消除与不在列表中的 mainsections 相关的所有部分。 但是调用脚本也被证明是一个挑战,因为 XSL 没有自己的方法来调用 javascript。

我对如何进行此操作有点无能为力...任何解决方案或建议?

源 XML 文档有 3500 行,其中的信息与此问题无关。问题是我如何过滤掉一个主要部分的子部分的子部分,或者:我如何确定一个子部分是否是指定主要部分中的一个子部分在树上几步。 考虑输入提到的 5 个小节,那么输出应该是:

<section uniqueName="national_news">
  <parent uniqueName="news"/>
</section>

<section uniqueName="regional_news">
  <parent uniqueName="national_news"/>
</section>

<section uniqueName="city_news">
  <parent uniqueName="regional_news"/>
</section>

自从

<section uniqueName="travel_europe">
  <parent uniqueName="travel"/>
</section>

<section uniqueName="holland">
  <parent uniqueName="travel_europe"/>
</section>

与“旅行”主要部分有关,不在要复制的列表中。

【问题讨论】:

  • 请编辑问题并提供所需的确切转换结果——如果没有显示,那么这个问题是关于什么的?还要提供源 XML 文档——我们不必猜测如何将小片段组合在一起。并且建议不要说“等”。
  • 见问题(底部)。等等表示还有500个其他类似的陈述,要我一一提到吗??

标签: xml xslt reference refer


【解决方案1】:

这种转变

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:param name="pWanted" select="'|news|sport|'"/>

 <xsl:key name="kChildren" match="section" use="parent/@uniqueName"/>

 <xsl:template match="/*">
     <xsl:call-template name="getSections">
       <xsl:with-param name="pParents" select=
       "section[contains($pWanted, concat('|',@uniqueName, '|'))]"/>
     </xsl:call-template>
 </xsl:template>

 <xsl:template name="getSections">
  <xsl:param name="pParents" select="/.."/>

  <xsl:if test="$pParents">
    <xsl:copy-of select="$pParents"/>
    <xsl:call-template name="getSections">
     <xsl:with-param name="pParents"
        select="key('kChildren', $pParents/@uniqueName)"/>
    </xsl:call-template>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

当应用于以下 XML 文档时(没有提供!!!):

<t>
    <section uniqueName="news"></section>
    <section uniqueName="sport"></section>
    <section uniqueName="travel"></section>
    <section uniqueName="national_news">
        <parent uniqueName="news"/>
    </section>
    <section uniqueName="regional_news">
        <parent uniqueName="national_news"/>
    </section>
    <section uniqueName="city_news">
        <parent uniqueName="regional_news"/>
    </section>
    <section uniqueName="travel_europe">
        <parent uniqueName="travel"/>
    </section>
    <section uniqueName="holland">
        <parent uniqueName="travel_europe"/>
    </section>
</t>

产生想要的(问题中没有明确说明!!!),正确的结果

<section uniqueName="news"/>
<section uniqueName="sport"/>
<section uniqueName="national_news">
   <parent uniqueName="news"/>
</section>
<section uniqueName="regional_news">
   <parent uniqueName="national_news"/>
</section>
<section uniqueName="city_news">
   <parent uniqueName="regional_news"/>
</section>

解释

正确使用 keys 和递归。

【讨论】:

  • 我对 XSL 还是很陌生,以为我已经掌握了它,但目前这超出了我的技能范围。仍在弄清楚你在那里做了什么,但这正是我想要的。非常感谢你!这两天一直让我头疼……
猜你喜欢
  • 2017-10-09
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多