Xml 如何使用xslt在父级<;元素>;可能有孩子<;元素>;这需要不同的逻辑
因此,我正在处理一个结构与此类似的xml文档 原始XML: 正常元素Xml 如何使用xslt在父级<;元素>;可能有孩子<;元素>;这需要不同的逻辑,xml,xslt,Xml,Xslt,因此,我正在处理一个结构与此类似的xml文档 原始XML: 正常元素 <element name="Name1"> <document> <number>A1</number> <reference>B1</reference> </document> </element> A1 地下一层 类似分组的元素 (为清晰起见,添加了根元素) A2 地下二层 A3 地下三层
<element name="Name1">
<document>
<number>A1</number>
<reference>B1</reference>
</document>
</element>
A1
地下一层
类似分组的元素
(为清晰起见,添加了根元素)
A2
地下二层
A3
地下三层
我想从这份文件中得到的是这样的东西
<references>
<reference>
<original>A1</original>
<mapping>B1</mapping>
</reference>
<reference>
<group id="Name2.xxx.Group">
<reference>
<original>A2</original>
<mapping>B2</mapping>
</reference>
<reference>
<original>A3</original>
<mapping>B3</mapping>
</reference>
</group>
</reference>
</references>
A1
地下一层
A2
地下二层
A3
地下三层
我很难想出一个很好的方法来做到这一点,因为元素上的匹配似乎匹配所有元素
到目前为止,我已经做到了这一点,但意识到它将不起作用,因为父元素和子元素具有相同的名称,但每个元素都需要一些不同的逻辑
<xsl:template match="/">
<xsl:element name="references">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="element">
<xsl:element name="reference">
<xsl:if test="element/document">
<xsl:element name="original">
<xsl:value-of select="element/document/number"/>
</xsl:element>
<xsl:element name="mapping">
<xsl:value-of select="element/document/reference"/>
</xsl:element>
<xsl:element name="id">
<xsl:value-of select="@id"/>
</xsl:element>
</xsl:if>
</xsl:element>
</xsl:template>
很难准确回答您的问题,因为您的第二个输入示例不是格式良好的XML(没有单个根元素),并且您的输出显示了来自两个输入示例的数据 以下样式表: XSLT1.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="/root">
<references>
<xsl:apply-templates/>
</references>
</xsl:template>
<xsl:template match="element[@id]">
<group id="{@id}">
<xsl:apply-templates/>
</group>
</xsl:template>
<xsl:template match="element">
<reference>
<original>
<xsl:value-of select="document/number"/>
</original>
<mapping>
<xsl:value-of select="document/reference"/>
</mapping>
</reference>
</xsl:template>
</xsl:stylesheet>
应用于第一个输入示例时,将返回:
<?xml version="1.0" encoding="UTF-8"?>
<reference>
<original>A1</original>
<mapping>B1</mapping>
</reference>
A1
地下一层
当应用于以下已更正的输入示例时:
<root>
<element name="Name2.Group" id="Name2.xxx.Group">
<element name="Name3">
<document>
<number>A2</number>
<reference>B2</reference>
</document>
</element>
<element name="Name4">
<document>
<number>A3</number>
<reference>B3</reference>
</document>
</element>
</element>
</root>
A2
地下二层
A3
地下三层
结果将是:
<?xml version="1.0" encoding="UTF-8"?>
<references>
<group id="Name2.xxx.Group">
<reference>
<original>A2</original>
<mapping>B2</mapping>
</reference>
<reference>
<original>A3</original>
<mapping>B3</mapping>
</reference>
</group>
</references>
A2
地下二层
A3
地下三层
这类任务的规范方法是应用身份转换,并对输出中看起来不同的节点进行修改
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" encoding="UTF-8" indent="yes" />
<xsl:strip-space elements="*" />
<!-- identity transform - copy everything unless another template fits -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<!-- the document element becomes <references> -->
<xsl:template match="/*">
<references>
<xsl:apply-templates select="@*|node()" />
</references>
</xsl:template>
<!-- <element> becomes <reference> -->
<xsl:template match="element">
<reference>
<xsl:apply-templates select="@*|node()" />
</reference>
</xsl:template>
<!-- <element> with group becomes <group> -->
<xsl:template match="element[contains(@name, '.Group')]">
<group>
<xsl:apply-templates select="@*|node()" />
</group>
</xsl:template>
<!-- we don't want to see element/@name in the output -->
<xsl:template match="element/@name" />
<!-- <document> is stepped over (just process the children) -->
<xsl:template match="element/document">
<xsl:apply-templates select="@*|node()" />
</xsl:template>
<!-- <number> becomes <original> -->
<xsl:template match="element/*/number">
<original>
<xsl:apply-templates select="@*|node()" />
</original>
</xsl:template>
<!-- <reference> becomes <mapping> -->
<xsl:template match="element/*/reference">
<mapping>
<xsl:apply-templates select="@*|node()" />
</mapping>
</xsl:template>
</xsl:transform>
输出,当应用于
<x>
<element name="Name1">
<document>
<number>A1</number>
<reference>B1</reference>
</document>
</element>
<element name="Name2.Group" id="Name2.xxx.Group">
<element name="Name3">
<document>
<number>A2</number>
<reference>B2</reference>
</document>
</element>
<element name="Name4">
<document>
<number>A3</number>
<reference>B3</reference>
</document>
</element>
</element>
</x>
A1
地下一层
A2
地下二层
A3
地下三层
会是
<references>
<reference>
<original>A1</original>
<mapping>B1</mapping>
</reference>
<group id="Name2.xxx.Group">
<reference>
<original>A2</original>
<mapping>B2</mapping>
</reference>
<reference>
<original>A3</original>
<mapping>B3</mapping>
</reference>
</group>
</references>
A1
地下一层
A2
地下二层
A3
地下三层
是的,很抱歉,我试图删去元素的细节,然后用最基本的例子说明我的问题所在。我在xml示例中的意思是假设显示的两个父元素都包装在某个元素中,这意味着它们都在同一个文档中。我试试看
<references>
<reference>
<original>A1</original>
<mapping>B1</mapping>
</reference>
<group id="Name2.xxx.Group">
<reference>
<original>A2</original>
<mapping>B2</mapping>
</reference>
<reference>
<original>A3</original>
<mapping>B3</mapping>
</reference>
</group>
</references>