我在下面的代码中有两个问题需要帮助修复:
1)从XPath表达式返回结果时,它不包含根节点。 (我尝试了几件事,但它更加混乱了结果......)
2)我需要帮助修复结果的格式。我需要在一个标题下列出具有相同属性的相同节点,而不是每个结果都有一个标题。我之前有一个 similar question ,但现在修复了代码问题,我似乎无法在不影响结果的情况下正常工作。
除了缺少根节点的问题,我相信这会返回正确的结果,因此我不想大幅改变代码。
以下是我正在测试的一些故意不一致的虚拟XML:
<pets name="myPets" NUM="2">
<dog name="allMyDogs" NUM="5">
<dog name="Frank" cute="yes" color"brown" type="Lab" NUM="3"/>
<dog name="Frank" NUM="3"/>
<dog name="Spot" NUM="4"/>
<dog name="Rover" cute="yes" NUM="1"/>
<dog name="Rupert" cute="yes" type="Pug" color="black" NUM="6"/>
<cat name="Lucy" cute="yes" NUM="4"/>
</dog>
<cat name="allMyCats" NUM="4">
<cat name="Simba" cute="yes" NUM="4"/>
<cat name="Princess" cute="no" color="black" NUM="5"/>
<cat name="Fluffy" cute="yes" color="grey" NUM="1"/>
<cat name="Lucy" cute="yes" color="brown" NUM="3">
<cat name="Lucy" cute="no" NUM="35"/>
<cat name="Lucy" cute="yes" purrs="yes" NUM="6"/>
</cat>
<cat name="Lucy"cute="no" color="grey" NUM="1"/>
<dog name="Rover" cute="yes" NUM="24"/>
</cat>
<cat name="Lucy" NUM="9"/>
<dog name="Rupert Jr" cute="yes" type="Pug" color="black" NUM="0"/>
</pets>
这是XSLT代码:
<xsl:key name="elem_key" match="elem" use="concat(@key, .)" />
<xsl:variable name="all_data">
<xsl:apply-templates select="*//*">
<xsl:sort select="name()" />
</xsl:apply-templates>
</xsl:variable>
<xsl:template match="//*[@NUM<=4]">
<elem key="{name()}">
<xsl:copy-of select="@*" />
<xsl:for-each select="@*">
<xsl:sort select="name()" />
<attribute>|<xsl:value-of select="name()" />|</attribute>
</xsl:for-each>
</elem>
</xsl:template>
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="msxsl:node-set($all_data)">
<xsl:for-each select="*[generate-id()=generate-id(key('elem_key',concat(@key, .))[1])]">
<table >
<tr>
<td>Element Name</td>
<xsl:for-each select="*">
<td>
<xsl:value-of select="translate(.,'|','')" />
</td>
</xsl:for-each>
</tr>
<xsl:for-each select="key('elem_key', concat(@key, .))">
<xsl:variable name="curr_elem" select="." />
<tr>
<td>
<xsl:value-of select="@key" />
</td>
<xsl:for-each select="*">
<td >
<xsl:value-of select="$curr_elem/@*[name()=translate(current(),'|','')]" />
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
<p />
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
输出所需的格式:
Element Name Name NUM
pets myPets 2
Element Name Name Cute Color NUM Type
dog Frank yes brown 3 Lab
dog Rupert Jr yes black 0 Pug
Element Name Name NUM
dog Frank 3
dog Spot 4
Element Name Name Cute NUM
dog Rover yes 1
Element Name Name Cute NUM
cat Lucy yes 4
cat Simba yes 4
Element Name Name NUM
cat allMyCats 4
Element Name Name Color Cute NUM
cat Fluffy grey yes 1
cat Lucy brown yes 3
cat Lucy grey no 1
谢谢! :)如果我需要清除任何内容,请告诉我!
答案 0 :(得分:2)
此转换修复了所有上述问题:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl">
<xsl:key name="elem_key" match="elem" use="." />
<xsl:key name="elem_key2" match="elem"
use="concat(@key, @name, .)" />
<xsl:variable name="all_data">
<xsl:apply-templates select="//*[@NUM<=4]">
<xsl:sort select="name()" />
</xsl:apply-templates>
</xsl:variable>
<xsl:template match="*">
<elem key="{name()}">
<xsl:copy-of select="@*" />
<xsl:for-each select="@*">
<xsl:sort select="name()" />
<attribute>|<xsl:value-of select="name()" />|</attribute>
</xsl:for-each>
</elem>
</xsl:template>
<xsl:template match="/">
<html>
<body>
<xsl:for-each select="msxsl:node-set($all_data)">
<xsl:for-each select=
"*[generate-id()
=
generate-id(key('elem_key',.)[1])
]">
<table >
<tr>
<td>Element Name</td>
<xsl:for-each select="*">
<td>
<xsl:value-of select=
"translate(.,'|','')" />
</td>
</xsl:for-each>
</tr>
<xsl:for-each select="key('elem_key',.)">
<xsl:variable name="curr_elem" select="." />
<tr>
<td>
<xsl:value-of select="@key" />
</td>
<xsl:for-each select="*">
<td >
<xsl:value-of select=
"$curr_elem/@*
[name()
=
translate(current(),
'|',
''
)
]" />
</td>
</xsl:for-each>
</tr>
</xsl:for-each>
</table>
<p />
</xsl:for-each>
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
将此转换应用于提供的XML文档:
<pets name="myPets" NUM="2">
<dog name="allMyDogs" NUM="5">
<dog name="Frank" cute="yes" color="brown" type="Lab" NUM="3"/>
<dog name="Frank" NUM="3"/>
<dog name="Spot" NUM="4"/>
<dog name="Rover" cute="yes" NUM="1"/>
<dog name="Rupert" cute="yes" type="Pug" color="black" NUM="6"/>
<cat name="Lucy" cute="yes" NUM="4"/>
</dog>
<cat name="allMyCats" NUM="4">
<cat name="Simba" cute="yes" NUM="4"/>
<cat name="Princess" cute="no" color="black" NUM="5"/>
<cat name="Fluffy" cute="yes" color="grey" NUM="1"/>
<cat name="Lucy" cute="yes" color="brown" NUM="3">
<cat name="Lucy" cute="no" NUM="35"/>
<cat name="Lucy" cute="yes" purrs="yes" NUM="6"/>
</cat>
<cat name="Lucy" cute="no" color="grey" NUM="1"/>
<dog name="Rover" cute="yes" NUM="24"/>
</cat>
<cat name="Lucy" NUM="9"/>
<dog name="Rupert Jr" cute="yes" type="Pug" color="black" NUM="0"/>
</pets>
生成了想要的结果:
<html>
<body>
<table>
<tr>
<td>Element Name</td>
<td>cute</td>
<td>name</td>
<td>NUM</td>
</tr>
<tr>
<td>cat</td>
<td>yes</td>
<td>Lucy</td>
<td>4</td>
</tr>
<tr>
<td>cat</td>
<td>yes</td>
<td>Simba</td>
<td>4</td>
</tr>
<tr>
<td>dog</td>
<td>yes</td>
<td>Rover</td>
<td>1</td>
</tr>
</table>
<p></p>
<table>
<tr>
<td>Element Name</td>
<td>name</td>
<td>NUM</td>
</tr>
<tr>
<td>cat</td>
<td>allMyCats</td>
<td>4</td>
</tr>
<tr>
<td>dog</td>
<td>Frank</td>
<td>3</td>
</tr>
<tr>
<td>dog</td>
<td>Spot</td>
<td>4</td>
</tr>
<tr>
<td>pets</td>
<td>myPets</td>
<td>2</td>
</tr>
</table>
<p></p>
<table>
<tr>
<td>Element Name</td>
<td>color</td>
<td>cute</td>
<td>name</td>
<td>NUM</td>
</tr>
<tr>
<td>cat</td>
<td>grey</td>
<td>yes</td>
<td>Fluffy</td>
<td>1</td>
</tr>
<tr>
<td>cat</td>
<td>brown</td>
<td>yes</td>
<td>Lucy</td>
<td>3</td>
</tr>
<tr>
<td>cat</td>
<td>grey</td>
<td>no</td>
<td>Lucy</td>
<td>1</td>
</tr>
</table>
<p></p>
<table>
<tr>
<td>Element Name</td>
<td>color</td>
<td>cute</td>
<td>name</td>
<td>NUM</td>
<td>type</td>
</tr>
<tr>
<td>dog</td>
<td>brown</td>
<td>yes</td>
<td>Frank</td>
<td>3</td>
<td>Lab</td>
</tr>
<tr>
<td>dog</td>
<td>black</td>
<td>yes</td>
<td>Rupert Jr</td>
<td>0</td>
<td>Pug</td>
</tr>
</table>
<p></p>
</body>
</html>