XSLT-foreach内部xml的其他部分的查找值

时间:2019-03-29 08:45:35

标签: xslt

我有以下XML。

<?xml version="1.0" ?>
<Root xmlns="http://1.local/1.xsd">
    <Definitions>
        <FileTypes>
            <FileType ID="1" Name="FileType1"/>
            <FileType ID="2" Name="FileType2"/>
            <!--... - lots of file types-->
        <FileTypes>
    </Definitions>
    <Files>
        <File Name="File1" FileTypeID="1" />
        <File Name="File2" FileTypeID="1" />
        <File Name="File3" FileTypeID="2" />
        <!--... - lots of files-->
    <Files>
</Root>

对于每个文件,我需要获取其Name属性,并为其FileTypeID查找对应的文件类型名称

因此示例输出为: 文件名:File1 文件类型:FileType1

文件名:File2 文件类型:FileType1

文件名:File3 文件类型:FileType2

到目前为止,这是XSLT,但是我不确定如何查找文件类型的名称。

<?xml version="1.0"?>
<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:l="http://1.local/1.xsd"
  exclude-result-prefixes="l"
  version="1.0">
  <xsl:output method="text" omit-xml-declaration="yes" media-type="text/plain" />

  <xsl:template match="/">
    <xsl:apply-templates select="l:Root/l:Files" />
  </xsl:template>

  <xsl:template match="l:Root/l:Files">
    Why
    <xsl:for-each select="l:File">
          File name: <xsl:value-of select="@Name">
          File type:
      </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

3 个答案:

答案 0 :(得分:2)

在此处使用xsl:key查找文件类型

<xsl:key name="FileTypes" match="l:FileType" use="@ID" />

然后,要获取相关的FileType名称,您可以这样做

<xsl:value-of select="key('FileTypes', @FileTypeID)/@Name" />

尝试使用此XSLT

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:l="http://1.local/1.xsd"
  exclude-result-prefixes="l"
  version="1.0">
  <xsl:output method="text" omit-xml-declaration="yes" media-type="text/plain" />

  <xsl:key name="FileTypes" match="l:FileType" use="@ID" />

  <xsl:template match="/">
    <xsl:apply-templates select="l:Root/l:Files" />
  </xsl:template>

  <xsl:template match="l:Files">
    <xsl:for-each select="l:File">
          File name: <xsl:value-of select="@Name" />
          File type: <xsl:value-of select="key('FileTypes', @FileTypeID)/@Name" />
      </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

(请注意,您的XML格式不正确,因为您没有FileTypesFiles的正确结束标记。)

答案 1 :(得分:2)

如果要使用XSLT,需要首先了解其表达语言XPath来导航XML树,可以选择//l:FileType[@ID = current()/@FileTypeID]/@Name。或者,如Tim所言,在XSLT中,您可以使用键来有效地实现查找。

答案 2 :(得分:1)

您可以尝试以下XSL。

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:l="http://1.local/1.xsd"
  exclude-result-prefixes="l"
  version="1.0">
  <xsl:output method="text" omit-xml-declaration="yes" media-type="text/plain" />

  <xsl:template match="/">
    <xsl:apply-templates select="l:Root/l:Files" />
  </xsl:template>

  <xsl:template match="l:Root/l:Files">

    Why
    <xsl:for-each select="l:File">
          File name: <xsl:value-of select="@Name"/>
          File type: <xsl:value-of select="//l:FileTypes/l:FileType[@ID=current()/@FileTypeID]/@Name"/>
      </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

此外,您需要确保在xsl转换中放入正确的名称空间,以实际匹配XML中的值,并且在XML中缺少一些关闭标记。

为完整起见,我包含了用于解决方案的固定XML

<Root xmlns="http://1.local/1.xsd">
    <Definitions>
        <FileTypes>
            <FileType ID="1" Name="FileType1"/>
            <FileType ID="2" Name="FileType2"/>
            <!--... - lots of file types-->
        </FileTypes>
    </Definitions>
    <Files>
        <File Name="File1" FileTypeID="1" />
        <File Name="File2" FileTypeID="1" />
        <File Name="File3" FileTypeID="2" />
        <!--... - lots of files-->
    </Files>
</Root>