2012-06-14 61 views
2

给定一个节点,例如:根据任何属性的值获取数据

<SI elem1="TI" elem2="FN" elem3="4099450222" elem4="TM" elem5="4094110000" elem6="MT" elem7="SP" elem8="MC" elem9="DS" elem10="DA" elem11="16"/> 

我需要输出为“DA”如果任何属性是“DA”,或者下一个属性的值,如果任何属性是“BA”(即,如果elem7 =“BA elem8 =” 03"我希望“03”输出)

没有多个匹配的危险,因此,如果一个属性是“BA”,就不会有“DA”属性,但值可能出现在任何元素

我已经查看了属性::标签,但我不确定这是否能满足我的需求。

任何帮助非常感谢

+1

嗯,依靠你输入XML中的属性顺序,通常是shakey。请参阅http://stackoverflow.com/questions/2287861/xslt-display-attributes-in-specific-order。在任何情况下,我都不相信XSL检查前/后节点的轴可以应用于属性。 – Utkanos

+0

属性名称将永远是elem1,elem2等。有没有办法获得属性名称,然后在最后替换数字字符? – Jaloopa

+0

要获得节点或属性的名称,请使用'name()' – Utkanos

回答

3

我做了你的属性具有在形式elemN其中N = 1,2,3 ..., 名称的假设,他们相应地排序。

下面的XSLT:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"> 
    <xsl:output method="text" /> 
    <xsl:template match="/SI"> 
     <xsl:choose> 
      <xsl:when test="some $i in @* satisfies $i='DA'"> 
       <xsl:text>DA</xsl:text> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:variable name="attr" select="concat('elem', xs:decimal(substring-after(@*[.='BA']/name(), 'elem')) + 1)" /> 
       <xsl:value-of select="@*[name() = $attr]" /> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 

应用于以下输入XML:

<?xml version="1.0" encoding="UTF-8"?> 
<SI elem1="TI" elem2="FN" elem3="4099450222" elem4="TM" elem5="4094110000" elem6="MT" elem7="SP" elem8="MC" elem9="DS" elem10="DA" elem11="16" /> 

给出DA作为输出。

而且应用于下面的XML:

<?xml version="1.0" encoding="UTF-8"?> 
<SI elem1="TI" elem2="FN" elem3="4099450222" elem4="TM" elem5="4094110000" elem6="MT" elem7="BA" elem8="03" elem9="DS" elem10="DAs" elem11="16" /> 

给出03作为输出。

EDIT

这里的XSLT 1.0版本(下的Altova XMLSpy的测试):

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="text" /> 
    <xsl:template match="/"> 
     <xsl:apply-templates select="SI/@*" /> 
    </xsl:template> 

    <xsl:template match="@*"> 
     <xsl:choose> 
     <xsl:when test=". = 'DA'"> 
      <xsl:text>DA</xsl:text>  
     </xsl:when> 
     <xsl:when test=".='BA'"> 
      <xsl:variable name="attr" select="concat('elem', substring-after(name(), 'elem') + 1)" /> 
      <xsl:value-of select="/SI/@*[name() = $attr]" /> 
     </xsl:when> 
     <xsl:otherwise/> 
     </xsl:choose> 
    </xsl:template> 
</xsl:stylesheet> 
+0

接受它解决了这个问题,并且我发现它比下面的@dimitre的答案稍微可读,但是我设法进入生成XML并设置更容易获取的属性的C#代码。 – Jaloopa

+0

这是否依赖版本2.0?当在1.0样式表中尝试变量时,我得到以下错误:Expected token')',found'('。...(substring-after(@ * [。='TM']/name - >(< - - ),'elem'))+ 1) – Jaloopa

+0

@Jaloopa:正如您在样式表头中看到的那样,它适用于XSLT 2.0。你还没有提到你想要XSLT 1.0解决方案... – Lukasz

2

I need my output to be "DA" if any attribute is "DA", or the value of the next attribute if any attribute is "BA" (i.e. if elem7="BA elem8="03" I want "03" output)

There is no danger of multiple matches, so if an attribute is "BA", there will be no "DA" attribute, but the values could occur in any element

此单XPath表达式产生想要的值

string(/*/@*[. = 'DA'] 
     | 
     /*/@*[name() 
       = 
       concat('elem', substring-after(name(/*/@*[.='BA']), 'elem') +1)] 
     ) 

这里是彻底的变革:

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

<xsl:template match="/"> 
    <xsl:copy-of select= 
    "string(/*/@*[. = 'DA'] 
      | 
      /*/@*[name() 
        = 
        concat('elem', substring-after(name(/*/@*[.='BA']), 'elem') +1)] 
      )"/> 
</xsl:template> 
</xsl:stylesheet> 

可以看出这种变换只是计算XPath表达式并复制评价输出的结果。

当变换这个XML文档(你的第二种情况)施加:当在应用相同的变换

03 

<SI elem1="TI" 
    elem2="FN" 
    elem3="4099450222" 
    elem4="TM" 
    elem5="4094110000" 
    elem6="MT" 
    elem7="BA" 
    elem8="03" 
    elem9="DS" 
    elem10="DD" 
    elem11="16"/> 

结果是最初提供的XML文档(您的第一种情况):

<SI elem1="TI" 
    elem2="FN" 
    elem3="4099450222" 
    elem4="TM" 
    elem5="4094110000" 
    elem6="MT" 
    elem7="SP" 
    elem8="MC" 
    elem9="DS" 
    elem10="DA" 
    elem11="16"/> 

再次通缉,正确的结果产生

DA 

说明

正确使用XPath 工会运营商|和功能string()substring-after()name()的和`concat()

+0

+1我 - 比我的短! – Lukasz

+0

@LukaszBaran:你的也很好。我个人更喜欢避免任何有条件的指示。 +1。 –