XSLT使用字母过滤掉记录

时间:2014-01-21 21:31:09

标签: xslt filter records

我们要求在数字字段中过滤包含字符的记录并单独报告。我确实遇到了以下被回答的问题 - XPATH To filter out records with letters

但是有一种方法可以使用标记标记这些记录或将它们收集在变量中,因为我们需要将这些记录报告为无效记录。如果我们完全删除它们,问题是我们不知道哪些是无效的。

请建议。

谢谢!

输入:

<?xml version="1.0" encoding="UTF-8"?>
<payload>
    <records>
        <record>
            <number>123</number>
        </record>
        <record>
            <number>456</number>
        </record> 
        <record>
            <number>78A</number>
        </record> 
    </records>
</payload>

输出:

<?xml version="1.0" encoding="UTF-8"?>
<payload>
    <records>
        <record>
            <number>123</number>
        </record>
        <record>
            <number>456</number>
        </record> 
    </records>
</payload>

上面链接中的XSLT解决方案:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match="record[translate(number, '0123456789', '')]"/>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:0)

匹配后,输出原始元素和所需的任何“标志”(属性,注释,处理指令等)。

示例:

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

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

    <xsl:template match="record[string(number(number))='NaN']">
        <record invalid="true">
            <xsl:apply-templates select="@*|node()"/>
        </record>
    </xsl:template>

</xsl:stylesheet>

输出

<payload>
   <records>
      <record>
         <number>123</number>
      </record>
      <record>
         <number>456</number>
      </record>
      <record invalid="true">
         <number>78A</number>
      </record>
   </records>
</payload>

如果您愿意,仍然可以使用原始匹配。


修改以处理多个number(字段)并识别record级别的特定字段(列)。

修改后的XML输入示例:

<payload>
    <records>
        <record>
            <number>123</number>
        </record>
        <record>
            <number>456</number>
        </record> 
        <record>
            <number>321</number>
            <number>78A</number>
            <number>654</number>
            <number>abc</number>
        </record> 
    </records>
</payload>

更新了XSLT 1.0

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

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

    <xsl:template match="record">
        <xsl:variable name="invalidCols">
            <xsl:apply-templates select="*" mode="invalid"/>
        </xsl:variable>
        <record>
            <xsl:if test="string($invalidCols)">
                <xsl:attribute name="invalidCols">
                    <xsl:value-of select="normalize-space($invalidCols)"/>
                </xsl:attribute>
            </xsl:if>
            <xsl:apply-templates select="@*|node()"/>
        </record>
    </xsl:template>

    <xsl:template match="number[string(number(.))='NaN']" mode="invalid">
        <xsl:number/>
        <xsl:text> </xsl:text>
    </xsl:template>

    <xsl:template match="*" mode="invalid"/>

</xsl:stylesheet>

<强>输出

<payload>
   <records>
      <record>
         <number>123</number>
      </record>
      <record>
         <number>456</number>
      </record>
      <record invalidCols="2 4">
         <number>321</number>
         <number>78A</number>
         <number>654</number>
         <number>abc</number>
         <number>123456</number>
      </record>
   </records>
</payload>