处理嵌套节点的最佳方法(不同的名称,相同的内容)

Posted

技术标签:

【中文标题】处理嵌套节点的最佳方法(不同的名称,相同的内容)【英文标题】:Optimal method to handle nesting nodes (Different name, same content) 【发布时间】:2021-12-01 21:43:50 【问题描述】:

我必须转换如下所示的 xml 消息。 每个节点的源内容实际上是相同的,具有不同的节点名称(父项、子项、子项)。

我继承了一个 XSLT,它通过对每个案例进行硬编码来解决解决方案,几乎没有使用模板,它有大量重复的 XSLT。

我想知道我有哪些选项可以优化 XSLT 以减少 XSLT 的重复。

我尝试为通用“节点”设置单个模板;然后尝试使用调用模板; 但是我无法弄清楚如何在泛型中嵌套对象

任何帮助表示赞赏,谢谢。

<item>
    <itemdetail>
        <parentitem>
            <item>001</item>
            <code1>1</code1>
            <code2>2</code2>
            <itemattribute>
                <item_desc>ParentItem</item_desc>
            </itemattribute>
        </parentitem>
        <childitem>
            <item>002</item>
            <code1>2</code1>
            <code2>2</code2>
            <itemattribute>
                <item_desc>ChildItemLevel1</item_desc>
            </itemattribute>
        </childitem>
        <subchildren>
            <subchild>
                <item>003</item>
                <code1>2</code1>
                <code2>1</code2>
                <itemattribute>
                    <item_desc>SubChild003</item_desc>
                </itemattribute>
            </subchild>
            <subchild>
                <item>004</item>
                <code1>2</code1>
                <code2>1</code2>
                <itemattribute>
                    <item_desc>SubChild004</item_desc>
                </itemattribute>
            </subchild>
        </subchildren>
    </itemdetail>
</item>

消息有几种变体 所需的转换需要如下所示。

Parent 和 Child 将只有 0 或 1 个实例 子级嵌套在父级下 SubChild(ren) 嵌套在 Child 下
Case parentitem Node ChildItem Present SubChildren Present
Case 1 Y Y Y
Case 2 Y N N
Case 3 Y Y N
Case 4 N Y N
Case 5 N Y Y
Case 6 N N Y

案例一

<Products>
        <Product type="parentitem">
            <item>001</item>
            <code1>1</code1>
            <code2>2</code2>
            <itemattribute>
                <item_desc>parentitem</item_desc>
            </itemattribute>
            <Product type="childitem">
                <item>002</item>
                <code1>2</code1>
                <code2>2</code2>
                <itemattribute>
                    <item_desc>childitem</item_desc>
                </itemattribute>
                <Product type="subchild">
                    <item>003</item>
                    <code1>2</code1>
                    <code2>1</code2>
                    <itemattribute>
                        <item_desc>SubChild003</item_desc>
                    </itemattribute>
                </Product>
                <Product type="subchild">
                    <item>004</item>
                    <code1>2</code1>
                    <code2>1</code2>
                    <itemattribute>
                        <item_desc>SubChild004</item_desc>
                    </itemattribute>
                </Product>
            </Product>
        </Product>
</Products>

案例 2

<Products>
        <Product type="parentitem">
            <item>001</item>
            <code1>1</code1>
            <code2>2</code2>
            <itemattribute>
                <item_desc>parentitem</item_desc>
            </itemattribute>
        </Product>
</Products>

案例 3

<Products>
        <Product type="parentitem">
            <item>001</item>
            <code1>1</code1>
            <code2>2</code2>
            <itemattribute>
                <item_desc>parentitem</item_desc>
            </itemattribute>
            <Product type="childitem">
                <item>002</item>
                <code1>2</code1>
                <code2>2</code2>
                <itemattribute>
                    <item_desc>childitem</item_desc>
                </itemattribute>
                </Product>
            </Product>
        </Product>
</Products>

【问题讨论】:

【参考方案1】:

这样的东西对你有用吗?我相信它涵盖的案例比您阐述的 6 个还要多。

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="itemdetail">
    <Products>
        <xsl:apply-templates select="parentitem"/>
        <xsl:apply-templates select="childitem[not(../parentitem)]"/>
        <xsl:apply-templates select="subchildren[not(../parentitem | ../childitem)]"/>
    </Products>
</xsl:template>

<xsl:template match="parentitem">
    <Product type="parentitem">
        <xsl:copy-of select="*"/>
        <xsl:apply-templates select="../childitem"/>
        <xsl:apply-templates select="../subchildren[not(../childitem)]"/>
    </Product>
</xsl:template>

<xsl:template match="childitem">
    <Product type="childitem">
        <xsl:copy-of select="*"/>
        <xsl:apply-templates select="../subchildren"/>
    </Product>
</xsl:template>

<xsl:template match="subchild">
    <Product type="subchild">
        <xsl:copy-of select="*"/>
    </Product>
</xsl:template>

</xsl:stylesheet>

【讨论】:

以上是关于处理嵌套节点的最佳方法(不同的名称,相同的内容)的主要内容,如果未能解决你的问题,请参考以下文章

比较具有相同数据但标记不同的两个 HTML 页面的最佳方法是啥

在嵌套集中重复节点名称

处理嵌套承诺的最佳方法(蓝鸟)[重复]

批处理文件以循环遍历文件夹并将文件夹和内容复制到具有相同文件夹名称的目录

python pandas - 处理嵌套 groupby 的最佳方法

方法签名最佳实践 - 重载与长名称