我有一个要求,我必须从不同的层次结构中提取和列出ID。下面是示例XML :(我提供了3级层次结构来反映肤色)
输入XML:
<Wrapper>
<A Id="A@1">
<B Id="B#1">
<C Id="C$1"/>
<C Id="C$2"/>
</B>
<B Id="B#2">
<C Id="C$3"/>
<C Id="C$4"/>
</B>
<B Id="B#3">
<C Id="C$5"/>
<C Id="C$6"/>
</B>
<B Id="B#4>
<C Id="C$7"/>
<C Id="C$8"/>
</B>
</A>
</Wrapper>
期望输出:
A Ids:
A@1
B Ids:
B#1
B#2
B#3
B#4
C Ids:
C$1
C$2
C$3
C$4
C$5
C$6
C$7
C$8
输入XSL:原理很简单:我遇到根元素&#34; \&#34;写下我提供的文本和每个层次结构绝对XPath 和访问ID ..这里是代码:
<?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"/>
<xsl:variable name="linefeed" select="' '"/>
<xsl:template match="/">
<!--List of A Ids-->
<xsl:text>A Ids:</xsl:text>
<xsl:value-of select="$linefeed"/>
<xsl:for-each select="/Wrapper/A/@Id">
<xsl:value-of select="concat(.,$linefeed)"/>
</xsl:for-each>
<xsl:value-of select="$linefeed"/>
<!--List of B Ids-->
<xsl:text>B Ids:</xsl:text>
<xsl:value-of select="$linefeed"/>
<xsl:for-each select="/Wrapper/A/B/@Id">
<xsl:value-of select="concat(.,$linefeed)"/>
</xsl:for-each>
<xsl:value-of select="$linefeed"/>
<!--List of C Ids-->
<xsl:text>C Ids:</xsl:text>
<xsl:value-of select="$linefeed"/>
<xsl:for-each select="/Wrapper/A/B/C/@Id">
<xsl:value-of select="concat(.,$linefeed)"/>
</xsl:for-each>
<xsl:value-of select="$linefeed"/>
</xsl:template>
</xsl:stylesheet>
有更好的方法吗?
答案 0 :(得分:2)
以下解决方案基于按名称对元素进行分组,而不是基于它们在层次结构中占据的位置。因此,即使
,此解决方案也会输出sam如果您想要一个基于文档中节点位置的通用解决方案,而不是使用他们的名称对它们进行分组,那么告诉我,我会尝试调整解决方案。同时这是我在'Muenchian Grouping'中的解决方案
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" indent="yes"/>
<xsl:variable name="linefeed" select="' '"/>
<!-- Use key to group elements by local-name -->
<xsl:key name="name-key" match="/Wrapper//*" use="local-name()"/>
<xsl:template match="Wrapper">
<!-- Obtain the first element for each group, where a group is
the set of elements sharing a name -->
<xsl:for-each select="//*[generate-id(.) = generate-id(key('name-key', local-name())[1])]">
<!-- Print header -->
<xsl:value-of select="concat(local-name(), ' Ids:', $linefeed)" />
<!-- Obtain all the nodes (children of Wrapper) with the local-name of
the current node using the previous key -->
<xsl:apply-templates select="key('name-key', local-name())" />
<!-- Print line feed at the end of each different group -->
<xsl:value-of select="$linefeed" />
</xsl:for-each>
</xsl:template>
<!-- Print the information for each element -->
<xsl:template match="*">
<xsl:value-of select="@Id" />
<xsl:value-of select="$linefeed" />
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:1)
一种解决方案可能是:
<?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"/>
<xsl:variable name="linefeed" select="' '"/>
<xsl:template match="/">
<!--List of A Ids-->
<xsl:text>A Ids:</xsl:text>
<xsl:value-of select="$linefeed"/>
<xsl:apply-templates select="//A" />
<!--List of B Ids-->
<xsl:text>B Ids:</xsl:text>
<xsl:value-of select="$linefeed"/>
<xsl:apply-templates select="//B" />
<!--List of C Ids-->
<xsl:text>C Ids:</xsl:text>
<xsl:value-of select="$linefeed"/>
<xsl:apply-templates select="//C" />
</xsl:template>
<xsl:template match="*">
<xsl:value-of select="@Id" />
<xsl:value-of select="$linefeed"/>
</xsl:template>
</xsl:stylesheet>