你能帮我一下吗?我有一个像这样的xml文件
<x:person>
<x:name>Angel</x:name>
<x:education-info>
<school>School ABC</school>
<address>address 123</address>
<city>city 1</city>
<year>2001</year>
<remarks>12334</remarks>
<school>School ABC2</school>
<address>address 456</address>
<city>city 2</city>
<year>2005</year>
<remarks>test1233</remarks>
</x:education-info>
<x:age>22</x:age>
</x:person>
如何在education-info标签中只获得学校和地址标签?然后格式化成XSLT格式像这样
School ABC - address 123
School ABC2 - address 456
XSLT 1.0
如果我首先使您的XML有效,它将看起来像下面这样,其效果是有些元素在名称空间urn:yourns
中,而有些元素不在名称空间中:
<x:person xmlns:x="urn:yourns">
<x:name>Angel</x:name>
<x:education-info>
<school>School ABC</school>
<address>address 123</address>
<city>city 1</city>
<year>2001</year>
<remarks>12334</remarks>
<school>School ABC2</school>
<address>address 456</address>
<city>city 2</city>
<year>2005</year>
<remarks>test1233</remarks>
</x:education-info>
<x:age>22</x:age>
</x:person>
现在,如果需要从这个输入获取数据,则需要确保在XSLT中匹配适当的名称空间。它不必匹配前缀,只要匹配命名空间即可。
下面的代码展示了如何通过使用模板以"XSLT方式"实现这一点。这可能看起来比第一个答案更多的代码,但它更容易更改:
<xsl:stylesheet version="1.0" xmlns:your="urn:yourns"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- select 'text', as your output suggests you only want text -->
<xsl:output method="text" />
<!-- ignore what we aren't interested in (this one is not req. with
your data, but help if your input is larger/different) -->
<xsl:template match="node()">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="text()" />
<!-- match parent x:education-info to only select what we are interested in
(this one can be left out as well, but more cleanly shows what you want to do)-->
<xsl:template match="your:education-info">
<xsl:apply-templates select="school | address" />
</xsl:template>
<!-- match school in no-namespace -->
<xsl:template match="school">
<xsl:value-of select="." />
<xsl:text> - </xsl:text>
</xsl:template>
<!-- match address in no-namespace -->
<xsl:template match="address">
<xsl:value-of select="." />
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
根据输入运行时的输出如下所示。点击这里在线查看。
School ABC - address 123
School ABC2 - address 456
XSLT 3.0
为了好玩,或者主要是因为您的示例显然是为了调用for-each-pair
而剪裁的,下面是XSLT 3.0中的一行代码(如果忽略臃肿的话):
<xsl:stylesheet version="3.0" xmlns:your="urn:yourns"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" />
<xsl:mode on-no-match="shallow-skip" />
<xsl:template match="your:education-info">
<xsl:value-of separator="
" select="
for-each-pair(school, address,
function($a, $b) {$a || ' - ' || $b })" />
</xsl:template>
</xsl:stylesheet>
类似于(我没有您的名称空间x,所以在这里省略):
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<xsl:for-each select="person/education-info/school">
<xsl:value-of select="."/>
<xsl:text> - </xsl:text>
<xsl:value-of select="following-sibling::address[1]"/>
<xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
这给了我:
School ABC - address 123
School ABC2 - address 456
编辑:在following-sibling中指定[1]只在第一个请求