XSL / XML检索属性。名称/价值对

时间:2009-08-27 12:26:15

标签: xml xslt

我有一个简单的xml文件,它是一个属性列表(名称/值对):

<?xml version="1.0" encoding="ISO-8859-1"?>
<Attrs>
   <Attr N="IsValid" V="true" />
   <Attr N="ID" V="99099" />
 </Attrs>

我想创建一个输出值的XSLT文件,但我似乎无法让它返回属性的值


这是我的xslt:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/Attrs">
    <xsl:if test="Attr[@N='IsValid']">
      --found IsValid        
      IsValid 1: <xsl:value-of select="current()/Attr[@V]"/> 
      IsValid 2: <xsl:value-of select="Attr[@V]"/> 
    </xsl:if>
    <xsl:if test="Attr[@N='ID']">
      --found ID
      ID 1: <xsl:value-of select="current()/Attr[@V]"/> 
      ID 2: <xsl:value-of select="Attr[@V]"/> 
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

在找到适当的属性Name(N ='name')后,我无法获得'V'属性的值。我不知道如何选择@V值。

这是我的输出:

<?xml version="1.0" encoding="utf-8"?>
--found IsValid        
IsValid 1:  
IsValid 2: 
--found ID
ID 1:  
ID 2: 

我在大多数情况下使用了Anthony的解决方案。我确实将模板匹配更改为仅使用Attr,然后使用选择stement来过滤我的名称。在大多数情况下,我只需要价值。在其他情况下,我需要自定义,这真的减少了我需要的模板数量。 (再次感谢帮助所有人的正确方向的开始)

<xsl:template match="Attr">
<xsl:choose>
   <xsl:when test="@N='IsValid'">
      <xsl:value-of select="@V" />
   </xsl:when>
   <xsl:otherwise>
      <xsl:value-of select="@V" />
    </xsl:otherwise>
</xsl:choose>
</xsl:template>

3 个答案:

答案 0 :(得分:3)

您应该使用这些路径

 current()/Attr/@V

Attr/@V

Xpath中[]的目的是描述一个谓词,这是一个必须是真元素的测试,如果要进行XPath,它就会被放置。

修改

试试这个: -

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/Attrs">
    <xsl:for-each match="Attr">
      <xsl:if test="@N='IsValid'">
       --found IsValid        
       IsValid 1: <xsl:value-of select="current()/@V"/> 
       IsValid 2: <xsl:value-of select="@V"/> 
      </xsl:if>
      <xsl:if test="@N='ID'">
        --found ID
        ID 1: <xsl:value-of select="current()/@V"/> 
        ID 2: <xsl:value-of select="@V"/> 
      </xsl:if>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

注意在谓词之外使用current()并没有多大意义,因为从输出中看到使用current()的路径与没有谓词的路径相同。

另一个更符合XSLT目标的版本(我也放弃了当前的())是: -

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/Attrs">
    <xsl:apply-templates />
  </xsl:template>  

  <xsl:template match="Attr[@N='IsValid']">
   --found IsValid        
   IsValid: <xsl:value-of select="@V" /> 
  </xsl:template>  

  <xsl:template match="Attr[@N='ID']">
    --found ID
    ID: <xsl:value-of select="@V"/> 
  </xsl:template>
</xsl:stylesheet>

答案 1 :(得分:1)

foreach很慢,像这样拆分模板:

**编辑:**你打败了我..

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="/Attrs">
    <xsl:apply-templates select="Attr" />  
  </xsl:template>
  <xsl:template match="Attr">
      <xsl:if test="@N='IsValid'">
       --found IsValid
        IsValid 2: <xsl:value-of select="@V"/>
       </xsl:if>
      <xsl:if test="@N='ID'">
        --found ID        
         ID 2: <xsl:value-of select="@V"/>
       </xsl:if>
  </xsl:template>
</xsl:stylesheet>

答案 2 :(得分:1)

首先,除非重要的是属性出现在哪个顺序,否则你应该用XML表示它们,因为属性,例如:

<element IsValid='true' ID='2'/>

名称/值对是 的XML属性。 (只要值不是疯狂的长字符串或对象层次结构。)

也就是说,这是一组简单的模板,可以满足您的需求:

<xsl:template match="Attrs">
   <output>
      <xsl:apply-templates select="Attr"/>
   </output>
</xsl:template>       

<xsl:template match="Attr[@N='IsValid']">
   <xsl:text>IsValid=</xsl:text>
   <xsl:value-of select="@V"/>
</xsl:template>

<xsl:template match="Attr[@N='ID']">
   <xsl:text>ID=</xsl:text>
   <xsl:value-of select="@V"/>
</xsl:template>