开发者

xslt matching tags different names

         <xsl:for-each select ="block4">
            <xsl:choose>
                <xsl:when test="tag[name = '57A']">
                    <xsl:value-of select="value"/>
                </xsl:when>
                <xsl:when test="tag[name = '57D'] ">
              开发者_运维百科      <xsl:value-of select="value"/>
                </xsl:when>
            </xsl:choose>,<xsl:text/>
        </xsl:for-each>

I have written my xslt like this. It's not working properly for this xml:

<tag>
  <name>57A</name> 
  <value>NORTESMM</value> 
</tag>

Sometimes the name of tags will change. It should be either 57A or 57D, as indicated in XSLT above. But it's not generating the proper outcome.


Change your select to:

<xsl:value-of select="tag/value"/>

Complete program:

XML:

<blocks>
  <block4>
    <tag>
      <name>57A</name>
      <value>NORTESMM</value>
    </tag>
  </block4>
  <block4>
    <tag>
      <name>57D</name>
      <value>FOO</value>
    </tag>
  </block4>
</blocks>

XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="blocks">
    <xsl:for-each select="block4">
      <xsl:choose>
        <xsl:when test="tag[name = '57A']">
          <xsl:value-of select="tag/value"/>
        </xsl:when>
        <xsl:when test="tag[name = '57D'] ">
          <xsl:value-of select="tag/value"/>
        </xsl:when>
      </xsl:choose>,<xsl:text/>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

OUTPUT:

NORTESMM,FOO


Try this

<xsl:for-each select ="block4">
<xsl:choose>
  <xsl:when test="tag/name = '57A'">
      <xsl:value-of select="tag/value"/>
  </xsl:when>
  <xsl:when test="tag/name = '57D'">
      <xsl:value-of select="tag/value"/>
  </xsl:when>
</xsl:choose>
</xsl:for-each>

You can test your XSLT with a simple XML, create two files test.xsl and data.xml and then open data.xml in Firefox for example:

data.xml

<?xml-stylesheet type="text/xsl" href="test.xsl"?> 
 <tag>
 <name>57A</name>
 <value>NORTESMM</value>
 </tag>

test.xsl

<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/">
        <html xmlns="http://www.w3.org/1999/xhtml">
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                <title></title>
            </head>
            <body>
            <xsl:for-each select ="block4">
            <xsl:choose>
                <xsl:when test="tag/name = '57A'">
                    <xsl:value-of select="tag/value"/>
                </xsl:when>
                <xsl:when test="tag/name = '57D'">
                    <xsl:value-of select="tag/value"/>              
                </xsl:when>
            </xsl:choose>
            </xsl:for-each>
            </body>
        </html>
    </xsl:template></xsl:stylesheet>


This is the shortest and the "most in the spirit of XSLT" solution:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="tag[name='57A']">value1 </xsl:template>
 <xsl:template match="tag[name='57D']">value2 </xsl:template>
</xsl:stylesheet>

when applied on this XML document:

<t>
    <tag>
        <name>57A</name>
        <value>NORTESMM</value>
    </tag>
    <tag>
        <name>57D</name>
        <value>NORTESMM</value>
    </tag>
</t>

the wanted, correct result is produced:

value1 value2 

Do note:

  1. We use and override the identity rule. This is the most fundamental and powerful XSLT design pattern.

  2. We don't use <xsl:for-each> and we don't use XSLT conditional instructions.

Solution 2:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <my:values>
  <val tagname="57A">value1 </val>
  <val tagname="57B">value2 </val>
  <val tagname="57C">value3 </val>
  <val tagname="57D">value4 </val>
  <val tagname="57E">value5 </val>
 </my:values>

 <xsl:variable name="vVals" select=
   "document('')/*/my:values/*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="tag">
  <xsl:value-of select="$vVals[@tagname=current()/name]"/>
 </xsl:template>
</xsl:stylesheet>

When applied on the same XML document (above), again the wanted, correct result is produced:

value1 value4 

Do note: This solution can be used when we want to treat many different possible values of tag/name. We use a table for the matching values and only a single overriding template.


<xsl:template match="block4/tag">
  <xsl:if test="name='57A' or name='57D'">
    <xsl:value-of select="value"/>
  </xsl:if>
  </xsl:text>, <xsl:text/>
</xsl:template>

It can differ depending on how <block4> and <tag> tags are structured.

Anyway I suggest you to learn XSLT first, at least the basics, and then to use it.


try

<xsl:for-each select ="block4">
            <xsl:choose>
                <xsl:when test="tag/name = '57A'">
                    <xsl:value-of select="value"/>
                </xsl:when>
                <xsl:when test="tag/name = '57D'">
                    <xsl:value-of select="value"/>
                </xsl:when>
            </xsl:choose>,<xsl:text/>
</xsl:for-each>
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜