将属性添加到每个xml节点xslt

时间:2016-07-26 13:01:06

标签: xslt

我试图使用xslt,please see example或更低版本来处理xml。另外,我喜欢为每个节点添加一个属性,表示节点的xpath。但我得到了问题

  

XTDE0420:无法创建父级为文档节点的属性节点(xpath)

我的例子xml是:

<?xml version="1.0" encoding="utf-16"?>
<shiporder xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" orderid="orderid1">
  <orderperson>orderperson1</orderperson>
  <shipto>
    <name>name1</name>
    <address>address1</address>
    <city>city1</city>
    <country>country1</country>
  </shipto>
  <item>
    <title>title1</title>
    <note>note1</note>
    <quantity>1</quantity>
    <price>1</price>
  </item>
  <item>
    <title>title2</title>
    <note>note2</note>
    <quantity>79228162514264337593543950335</quantity>
    <price>-79228162514264337593543950335</price>
  </item>
  <item>
    <title>title3</title>
    <note>note3</note>
    <quantity>2</quantity>
    <price>79228162514264337593543950335</price>
  </item>
  <item>
    <title>title4</title>
    <note>note4</note>
    <quantity>79228162514264337593543950334</quantity>
    <price>0.9</price>
  </item>
  <item>
    <title>title5</title>
    <note>note5</note>
    <quantity>3</quantity>
    <price>1.1</price>
  </item>
</shiporder>

我的转换xslt表看起来像:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:func="http://www.functx.com">
  <xsl:output method="xml" encoding="utf-8"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:attribute name="xpath">
            <xsl:value-of select="func:getXpath(.)"/>
        </xsl:attribute>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

   <xsl:function name="func:createXPath" >
    <xsl:param name="pNode" as="node()"/>
    <xsl:value-of select="$pNode/ancestor-or-self::*/name()" separator="/"/>
  </xsl:function>

  <xsl:function name="func:getXpath">
  <xsl:param name="pNode" as="node()"/>
   <xsl:value-of select="$pNode/ancestor-or-self::*/(count(preceding-sibling::*) + 1)" separator="/" />
</xsl:function> 

</xsl:stylesheet>

其他我喜欢结合名称和计数器的功能,结果看起来像nodeName [2] / nodeName [5] / ..

1 个答案:

答案 0 :(得分:3)

而不是:

if object_id('tempdb..#temp') is not null drop table #temp

declare @dt1 datetime, @dt2 datetime
set @dt1 = '2015-12-01' 
set @dt2 = '2015-12-31'

select '11/1/2015' as DT
into #temp
union all
select '12/15/2016'
union all
select '12/16/2017'
union all
select '1/1/2017'

select * from #temp
where 
    MONTH(DT) >= MONTH(@dt1) and MONTH(DT) <= MONTH(@dt2)
    and DATEPART(day,DT) >= DATEPART(day,@dt1) and DATEPART(day,DT) <= DATEPART(day,@dt2)

尝试:

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

注意:

  1. 您的输出方法应为<xsl:template match="@*|node()"> <xsl:copy> <xsl:attribute name="xpath">32</xsl:attribute> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> ,而不是xml;

  2. 如果您想使用text,那么您的版本应为xsl:function;

  3. 您的第一个模板是多余的。