【问题标题】:XSLT Apply Templates to derive specific parent & children records, children can be parent tooXSLT 应用模板来派生特定的父子记录,子节点也可以是父节点
【发布时间】:2023-04-06 22:04:02
【问题描述】:

我需要有关我的 XSLT 的帮助。这是我的 XML 结构。

<root>
<row>
    <component>mainfield_1</component>
    <type>Field</type>
    <where_used>
        <component>subfield_2</component>
        <type>Field</type>
    </where_used>
    <where_used>
        <component>report_1</component>
        <type>Report</type>
    </where_used>
</row>
<row>
    <component>subfield_2</component>
    <type>Field</type>
    <where_used>
        <component>report_2</component>
        <type>report</type>
    </where_used>
</row>
<row>
    <component>mainfield_3</component>
    <type>Field</type>
</row>
</root>

我希望将其转换为以下内容:

<root>
<row>
    <component>mainfield_1</component>
    <type>Field</type>
</row>
<row>
    <component>subfield_2</component>
    <type>Field</type>
</row>
<row>
    <component>report_1</component>
    <type>Report</type>
</row>
<row>
    <component>report_2</component>
    <type>report</type>
</row>
</root>

基本上,我正在尝试获取组件 mainfield_1 的所有不同依赖项。这是我的示例代码,但不足以找到任何与子组件名称相同的匹配父组件。

<xsl:template match="root">
    <root>
        <xsl:apply-templates select="row[component='mainfield_1']"/>
    </root>
</xsl:template>

<xsl:template match="row">
    <row>
        <component>
            <xsl:value-of select="component"/>
        </component>
        <type>
            <xsl:value-of select="type" />
        </type>
    </row>
    <xsl:apply-templates select="where_used"/>
</xsl:template>

<xsl:template match="where_used">
    <row>
        <component>
            <xsl:value-of select="component"/>
        </component>
        <type>
            <xsl:value-of select="type" />
        </type>
    </row>
</xsl:template>

如果我运行上面的,我将无法得到这个。

<row>
  <component>report_2</component>
  <type>report</type>
</row>

请帮忙。

【问题讨论】:

    标签: xslt xslt-1.0 xslt-2.0


    【解决方案1】:

    考虑使用键来查找componentrow 项目

    <xsl:key name="rows" match="row" use="component" />
    

    然后,您可以为 where_used 节点创建一个模板,该模板引用单独的行,从而允许您选择该行

    <xsl:template match="where_used[key('rows', component)]">
        <xsl:apply-templates select="key('rows', component)" />
    </xsl:template>
    

    试试这个 XSLT

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
        <xsl:output method="xml" indent="yes" />
    
        <xsl:key name="rows" match="row" use="component" />
    
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="root">
            <root>
                <xsl:apply-templates select="row[component='mainfield_1']"/>
            </root>
        </xsl:template>
    
        <xsl:template match="row">
            <row>
                <xsl:apply-templates select="* except where_used" />
            </row>
            <xsl:apply-templates select="where_used"/>
        </xsl:template>
    
        <xsl:template match="where_used">
            <row>
                <xsl:apply-templates />
            </row>
        </xsl:template>    
    
        <xsl:template match="where_used[key('rows', component)]">
            <xsl:apply-templates select="key('rows', component)" />
        </xsl:template>
    </xsl:stylesheet>
    

    注意我也使用了标识模板,以避免显式复制不需要更改的现有节点。

    【讨论】:

      猜你喜欢
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 2017-05-04
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      • 1970-01-01
      • 2017-12-07
      相关资源
      最近更新 更多