I am new to XSLT script. I have the input is like as follows:
<?xml version="1.0" encoding="utf-16"?>
<FileDescriptorSet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<file>
<FileDescriptorProto>
<name>Message</name>
<dependency />
<message_type>
<DescriptorProto>
<name>ABCD</name>
<field>
<FieldDescriptorProto>
<name>Type</name>
<number>10</number>
<type>TYPE_STRING</type>
</FieldDescriptorProto>
<FieldDescriptorProto>
<name>List</name>
<number>20</number>
<type>TYPE_STRING</type>
</FieldDescriptorProto>
</field>
</DescriptorProto>
<DescriptorProto>
<name>XYZ</name>
<field>
<FieldDescriptorProto>
<name>Instance</name>
<number>1</number>
**<type>ABCD</type>**
</FieldDescriptorProto>
</field>
</DescriptorProto>
</message_type>
</FileDescriptorProto>
</file>
</FileDescriptorSet>
在上面的例子中,它有2个DescriptorProto,即ABCD和XYZ。 第二个DescriptorProto XYZ引用了第一个DescriptorProto(ABCD)。 我的问题是当我在XYZ中遇到引用时如何导航到ABCD(在上面的代码中标记为**)。
基本上我想在XYZ中遇到 ABCD 引用时提取ABCD的定义。预期的输出如:
在XYZ下:
--Instance
--1
--Type
--10
--TYPE_STRING
--List
--20
--TYPE_STRING
答案 0 :(得分:0)
以下XSLT使用递归调用的模板生成所需的输出。初始调用是通过明确选择名称XYZ
给出的类型来完成的。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes" />
<!-- explicitly call for the initial type -->
<xsl:template match="/">
<xsl:apply-templates select="//DescriptorProto[name='XYZ']" mode="dump"/>
</xsl:template>
<!-- recursively handling -->
<xsl:template match="DescriptorProto" mode="dump">
<xsl:for-each select="field/FieldDescriptorProto">
<xsl:text>--</xsl:text><xsl:value-of select="name"/><xsl:text> </xsl:text>
<xsl:text>--</xsl:text><xsl:value-of select="number"/><xsl:text> </xsl:text>
<xsl:variable name="type_name" select="type"/>
<xsl:choose>
<xsl:when test="//DescriptorProto[name = $type_name]">
<!-- recurse using the type name -->
<xsl:apply-templates select="//DescriptorProto[name = $type_name]" mode="dump"/>
</xsl:when>
<xsl:otherwise>
<!-- no further recursion possible (due to base type); just output the type name -->
<xsl:text>--</xsl:text><xsl:value-of select="$type_name"/><xsl:text> </xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>