xslt删除属性的一部分

时间:2013-03-01 10:32:29

标签: xml xslt xslt-2.0

是否可以将属性从“book1chapter2”转换为“chapter2”?

例如此节点:

<a myAttribute="part1chapter2" />

应该变成

<a myAttribute="chapter2" />

我试过了:

<xsl:variable name="chapter" select="replace('part1chapter2', 'book1', '')" />

但是它会导致编译错误:

ERROR:  'Error checking type of the expression 'funcall(replace, [literal-expr(part1chapter2), literal-expr(part1), literal-expr()])'.'
FATAL ERROR:  'Could not compile stylesheet'

我使用的是XSLT 2.0版。

没有任何图书馆的解决方案将不胜感激:)

编辑:

Java代码,使用javac -g TestXslt.java编译和运行; java TestXslt;

public static void main(String[] args) throws IOException, URISyntaxException, TransformerException {
    TransformerFactory factory = TransformerFactory.newInstance();
    Source xslt = new StreamSource(new File("../transform.xslt"));
    Transformer transformer = factory.newTransformer(xslt);

    Source text = new StreamSource(new File("../input.xml"));
    String r = new String();
    StreamResult result = new StreamResult(new File("../output.xml"));
    transformer.transform(text, result);
}

Java版javac 1.6.0_27

3 个答案:

答案 0 :(得分:6)

我认为你想象样式表上的version =“2.0”会自动为你提供一个XSLT 2.0处理器。这不是它的工作方式。您获得的处理器由您的类路径中的内容决定,如果您选择默认的JDK处理器,它只支持XSLT 1.0。 XSLT 1.0的规范说如果它看到对诸如replace()之类的无法识别的函数的调用,它应该引发运行时错误。

要在XSLT 2.0下运行,请下载Saxon并确保它在您的类路径中。理想情况下,为了健壮性,不要依赖JAXP加载方法来查找它,而是明确加载它。而不是

TransformerFactory factory = TransformerFactory.newInstance();

DO

TransformerFactory factory = new net.sf.saxon.TransformerFactoryImpl();

答案 1 :(得分:1)

我不太确定您是否尝试更改属性内容或属性名称。

如果是前者,则替换函数参数是(input-string,regex,replacement-string),所以你可以尝试replace(@attributeToChange, 'book1chaper2', 'book1')之类的东西。 如果是后者,那么我认为你需要这样的东西:

<xsl:attribute name="book1">
    <xsl:value-of select="@book1chaper2"/>
</xsl:attribute>

修改

虽然您收到编译器错误但很奇怪。如果您的XSLT引擎中存在该函数的问题,则另一种方法(如果您要更改内容)将是:

<xsl:choose>
    <xsl:when test="@attributeToChange='book1chaper2'">
         <xsl:text>book1</xsl:text>
    </xsl:when>
    <xsl:otherwise>
         <xsl:value-of select="@attributeToChange"/>
    </xsl:otherwise>
</xsl:choose>

进一步编辑

听起来你的处理器可能是XSLT 1.0:

Error when running XSLT with eclipse

尝试在select-when-otherwise中使用starts-with(@attributeToChange, 'book1')作为测试。

答案 2 :(得分:0)

你可以这样做:

<xsl:variable name="chapter" select="substring-after('book1chapter2', 'book1', '')" />

但是值一开始会包含“book1”吗?您是否从其他地方获得“book1”值,因此总是知道要删除哪个部分?