xslt的嵌套XML标记



你能帮我一下吗?我有一个像这样的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>&#xa;</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="&#xA;" 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>&#xa;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

这给了我:

School ABC - address 123
School ABC2 - address 456

编辑:在following-sibling中指定[1]只在第一个请求

相关内容

  • 没有找到相关文章

最新更新