如何选择包含在变量中的节点?

时间:2016-05-25 17:05:25

标签: xml xslt

XML是在变量myvar中动态生成的。 然后,我想选择Line

MyDate != '99991231'个节点

这不起作用:

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

  <xsl:variable name="myvar"> 
    <output>
      <Line><LineNumber>1</LineNumber><MyDate>99991231</MyDate><Amt>10</Amt></Line>
      <Line><LineNumber>2</LineNumber><MyDate>20150131</MyDate><Amt>15</Amt></Line>
      <Line><LineNumber>3</LineNumber><MyDate>99991231</MyDate><Amt>20</Amt></Line>
      <Line><LineNumber>4</LineNumber><MyDate>20161231</MyDate><Amt>30</Amt></Line>
      <Line><LineNumber>5</LineNumber><MyDate>99991231</MyDate><Amt>40</Amt></Line>
      <Line><LineNumber>6</LineNumber><MyDate>20171231</MyDate><Amt>50</Amt></Line>
      <Line><LineNumber>7</LineNumber><MyDate>20140131</MyDate><Amt>60</Amt></Line>
    </output>
  </xsl:variable>

  <xsl:template match="/">
    <xsl:copy-of select="$myvar[Line/MyDate='99991231']"/>
  </xsl:template>

</xsl:stylesheet>

我想获得:

<output> 
  <Line><LineNumber>2</LineNumber><MyDate>20150131</MyDate><Amt>15</Amt></Line>
  <Line><LineNumber>4</LineNumber><MyDate>20161231</MyDate><Amt>30</Amt></Line>
  <Line><LineNumber>6</LineNumber><MyDate>20171231</MyDate><Amt>50</Amt></Line>
  <Line><LineNumber>7</LineNumber><MyDate>20140131</MyDate><Amt>60</Amt></Line>
</output>

任何提示?

3 个答案:

答案 0 :(得分:2)

XSLT 2.0解决方案

要复制$myvar Line个孩子不等于MyDate的{​​{1}}个元素:

99991231

您还必须将所选元素包装在一个公共元素中,以生成格式良好的XML。

答案 1 :(得分:2)

由于带有变量的Resulting-Tree-Fragment problem,提供纯粹且有效的 XSLT-1.0 解决方案并不容易。

因此,我将数据包装在数据岛而不是变量中,并使用the method from here来避免<copy-of>复制名称空间。

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:var="http://some.var" exclude-result-prefixes="var">
<xsl:output method="xml" indent="yes" />

<var:var>
  <output>
    <Line><LineNumber>1</LineNumber><MyDate>99991231</MyDate><Amt>10</Amt></Line>
    <Line><LineNumber>2</LineNumber><MyDate>20150131</MyDate><Amt>15</Amt></Line>
    <Line><LineNumber>3</LineNumber><MyDate>99991231</MyDate><Amt>20</Amt></Line>
    <Line><LineNumber>4</LineNumber><MyDate>20161231</MyDate><Amt>30</Amt></Line>
    <Line><LineNumber>5</LineNumber><MyDate>99991231</MyDate><Amt>40</Amt></Line>
    <Line><LineNumber>6</LineNumber><MyDate>20171231</MyDate><Amt>50</Amt></Line>
    <Line><LineNumber>7</LineNumber><MyDate>20140131</MyDate><Amt>60</Amt></Line>
  </output>
</var:var>

<xsl:template match="/">
  <output>
    <xsl:apply-templates select="document('')/xsl:stylesheet/var:var/output/Line[MyDate != '99991231']"/>
  </output>
</xsl:template>

<!-- Copy elements - solution from the second SO answer -->
<xsl:template match="*" priority="-1">
   <xsl:element name="{name()}">
      <xsl:apply-templates select="node()|@*"/>
   </xsl:element>
</xsl:template>

<!-- Copy all other nodes -->
<xsl:template match="node()|@*" priority="-2">
   <xsl:copy />      
</xsl:template>

</xsl:stylesheet>

这给出了所需的输出:

<?xml version="1.0"?>
<output>
  <Line>
    <LineNumber>2</LineNumber>
    <MyDate>20150131</MyDate>
    <Amt>15</Amt>
  </Line>
  <Line>
    <LineNumber>4</LineNumber>
    <MyDate>20161231</MyDate>
    <Amt>30</Amt>
  </Line>
  <Line>
    <LineNumber>6</LineNumber>
    <MyDate>20171231</MyDate>
    <Amt>50</Amt>
  </Line>
  <Line>
    <LineNumber>7</LineNumber>
    <MyDate>20140131</MyDate>
    <Amt>60</Amt>
  </Line>
</output>

答案 2 :(得分:1)

由于您似乎正在使用XSLT 1.0,因此您应该以这种方式尝试:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>

<xsl:variable name="myvar"> 
    <Line><LineNumber>1</LineNumber><MyDate>99991231</MyDate><Amt>10</Amt></Line>
    <Line><LineNumber>2</LineNumber><MyDate>20150131</MyDate><Amt>15</Amt></Line>
    <Line><LineNumber>3</LineNumber><MyDate>99991231</MyDate><Amt>20</Amt></Line>
    <Line><LineNumber>4</LineNumber><MyDate>20161231</MyDate><Amt>30</Amt></Line>
    <Line><LineNumber>5</LineNumber><MyDate>99991231</MyDate><Amt>40</Amt></Line>
    <Line><LineNumber>6</LineNumber><MyDate>20171231</MyDate><Amt>50</Amt></Line>
    <Line><LineNumber>7</LineNumber><MyDate>20140131</MyDate><Amt>60</Amt></Line>
 </xsl:variable>

<xsl:template match="/">
    <output>
        <xsl:copy-of select="exsl:node-set($myvar)/Line[MyDate != '99991231']"/>
    </output>
</xsl:template>

</xsl:stylesheet>
相关问题