具有相同级别下重复节点的 XSLT 变换
Posted
技术标签:
【中文标题】具有相同级别下重复节点的 XSLT 变换【英文标题】:XSLT transform with repeating node under same level 【发布时间】:2021-10-05 02:36:10 【问题描述】:我是 xslt 的新手。我正在学习 xslt 并且难以转换 xml 格式。 我有以下 xml 输入
```<Body>
<Grp Name="Root">
<Grp Name="Info">
<Parm Name="parent_id" Val="Id_1" />
<Grp Name="CurrenInfo">
<Parm Name="current_id" Val="Id_1A" />
<Grp Name="CurrentChildInfo">
<Parm Name="Name" Val="State1" />
<Parm Name="Value" Val="S1" />
</Grp>
<Grp Name="CurrentChildInfo">
<Parm Name="Name" Val="State2" />
<Parm Name="Value" Val="S2" />
</Grp>
</Grp>
<Grp Name="CurrenInfo">
<Parm Name="current_id" Val="Id_1B" />
<Grp Name="CurrentChildInfo">
<Parm Name="Name" Val="State3" />
<Parm Name="Value" Val="S3" />
</Grp>
</Grp>
</Grp>
</Grp>
</Body>`
我需要将其转换为以下格式.....
```<Info>
<parent_id>Id_1</parent_id>
<original_list>
<list>
<current_id>Id_1A</current_id>
<Name>State1</Name>
<Value>S1</Value>
</list>
<list>
<current_id>Id_1A</current_id>
<Name>State2</Name>
<Value>S2</Value>
</list>
<list>
<current_id>Id_1B</current_id>
<Name>State3</Name>
<Value>S3</Value>
</list>
</original_list>
<Info>```
以下是我目前的 xslt
```<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="Body">
<xsl:element name="Info">
<xsl:for-each select="//Grp[@Name='Root']/Grp[@Name='Info']">
<xsl:for-each select="Parm">
<xsl:element name="parent_id">
<xsl:value-of select="@Val"/>
</xsl:element>
</xsl:for-each>
<xsl:for-each select="//Grp[@Name='CurrenInfo']">
<xsl:element name="list">
<xsl:for-each select="Parm">
<xsl:element name="current_id">
<xsl:value-of select="@Val"/>
</xsl:element>
</xsl:for-each>
<xsl:for-each select="Grp[@Name='CurrentChildInfo']">
<xsl:for-each select="Parm">
<xsl:element name="@Name">
<xsl:value-of select="@Val"/>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>```
但是当我使用上面的 xslt 时输出格式如下
```<Info>
<parent_id>Id_1</parent_id>
<list>
<current_id>Id_1A</current_id>
<Name>State1</Name>
<Value>S1</Value>
<Name>State2</Name>
<Value>S2</Value>
</list>
<list>
<current_id>Id_1B</current_id>
<Name>State3</Name>
<Value>S3</Value>
</list>
</Info>```
需要帮助来纠正 xslt 以返回所需的格式 谢谢
【问题讨论】:
【参考方案1】:只做一些小的修改,你可以使用下面的样式表:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="Body">
<xsl:element name="Info">
<xsl:for-each select="Grp[@Name='Root']/Grp[@Name='Info']">
<xsl:for-each select="Parm">
<xsl:element name="parent_id">
<xsl:value-of select="@Val"/>
</xsl:element>
</xsl:for-each>
<original_list>
<xsl:for-each select=".//Grp[@Name='CurrentChildInfo']">
<xsl:element name="list">
<xsl:for-each select="../Parm">
<xsl:element name="current_id">
<xsl:value-of select="@Val"/>
</xsl:element>
</xsl:for-each>
<xsl:for-each select="Parm">
<xsl:element name="@Name">
<xsl:value-of select="@Val"/>
</xsl:element>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</original_list>
</xsl:for-each>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
它的输出是
<Info>
<parent_id>Id_1</parent_id>
<original_list>
<list>
<current_id>Id_1A</current_id>
<Name>State1</Name>
<Value>S1</Value>
</list>
<list>
<current_id>Id_1A</current_id>
<Name>State2</Name>
<Value>S2</Value>
</list>
<list>
<current_id>Id_1B</current_id>
<Name>State3</Name>
<Value>S3</Value>
</list>
</original_list>
</Info>
我从第一个xsl:for-each
中删除了//
,因为它似乎没有必要。但如果你想选择所有@Name='Root'
孩子,最好使用.//
。
【讨论】:
非常感谢。它按预期工作..祝你有美好的一天 我确实想知道这种答案是否 OP 真的理解了为什么他们的代码不起作用,并且会避免再次犯同样的错误。 嗨 MK,我明白我原来代码中的错误,谢谢你的关心..以上是关于具有相同级别下重复节点的 XSLT 变换的主要内容,如果未能解决你的问题,请参考以下文章
如何合并具有“相同父亲”、相同方法和相同 id=0 的两个节点(使用 XSLT)?
如何合并具有“相同父亲”和具有精确“方法”序列的两个节点(使用 XSLT)?
使用 XSLT 组合具有相同 ID 及其值的节点 (XML)