我需要在XSLT处理期间在整个文档中删除属性的子集。在以下XML示例中,我想删除仅包含数字的@id
属性。对于@id
的其余部分,它们不会更改。
<?xml-stylesheet type="text/xsl" href="recursion2.xsl" ?>
<list>
<book id="B1">
<label>1</label>
<title id="1">A Good Story</title>
<author>James Soul</author>
</book>
<book id="B2">
<label>2</label>
<title id="21">The Perfect Storm</title>
<author>Laura Smith</author>
</book>
<journal id="J1">
<label>3</label>
<citation id="3">Tom Lane. The smart computation method. 2003;23(5):123-128.</citation>
</journal>
<journal id="J2">
<label>4</label>
<citation id="122">Luna Shen. The identification of new gene, SMACT4. 2010;10(2):23-38. </citation>
</journal>
</list>
预期结果应为:
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="recursion2.xsl" ?>
<list>
<book id="B1">
<label>1</label>
<title>A Good Story</title>
<author>James Soul</author>
</book>
<book id="B2">
<label>2</label>
<title>The Perfect Storm</title>
<author>Laura Smith</author>
</book>
<journal id="J1">
<label>3</label>
<citation>Tom Lane. The smart computation method. 2003;23(5):123-128.</citation>
</journal>
<journal id="J2">
<label>4</label>
<citation>Luna Shen. The identification of new gene, SMACT4. 2010;10(2):23-38. </citation>
</journal>
</list>
我尝试了以下代码,并认为test="number(@id)=@id"
会选择仅包含数字的@id
,但所有@id
都已删除。
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="@id">
<xsl:apply-templates select="@* | node()"/>
</xsl:template>
<xsl:template>
<xsl:if test="number(@id)=@id"/>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:2)
您可以尝试使用以下模板,该模板仅在值不是数字时处理@id
。
<xsl:template match="@id">
<xsl:if test="not(number(.))">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:if>
</xsl:template>
完成XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:strip-space elements="*" />
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="@id">
<xsl:if test="not(number(.))">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
输出
<list>
<book id="B1">
<label>1</label>
<title>A Good Story</title>
<author>James Soul</author>
</book>
<book id="B2">
<label>2</label>
<title>The Perfect Storm</title>
<author>Laura Smith</author>
</book>
<journal id="J1">
<label>3</label>
<citation>Tom Lane. The smart computation method. 2003;23(5):123-128.</citation>
</journal>
<journal id="J2">
<label>4</label>
<citation>Luna Shen. The identification of new gene, SMACT4. 2010;10(2):23-38. </citation>
</journal>
</list>
答案 1 :(得分:1)
从this post about testing the first character of attributes to be a non-numeric value的提示中,我找到了我想要的解决方案:
<xsl:template match="@id[string(number(substring(.,1,1))) !='NaN']" />
此代码将删除以数字值开头的所有@id
,这足以满足我的需要。原帖有很多很好的解释。