1

是否可以将属性从 "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

4

3 回答 3

6

我认为您认为在样式表上说 version="2.0" 会自动获得 XSLT 2.0 处理器。这不是它的工作方式。您获得的处理器取决于您的类路径中的内容,如果您选择默认的 JDK 处理器,它仅支持 XSLT 1.0。XSLT 1.0 的规范说,如果它看到对像 replace() 这样的无法识别的函数的调用,它应该引发运行时错误。

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

TransformerFactory factory = TransformerFactory.newInstance();

TransformerFactory factory = new net.sf.saxon.TransformerFactoryImpl();
于 2013-03-01T11:26:18.057 回答
1

我不太确定您是要更改属性内容还是属性名称。

如果是前者,则替换函数参数为(输入字符串、正则表达式、替换字符串),因此您可以尝试类似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:

使用 eclipse 运行 XSLT 时出错

尝试starts-with(@attributeToChange, 'book1')在选择时用作测试,否则。

于 2013-03-01T10:53:00.867 回答
0

你可以简单地这样做:

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

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

于 2013-03-01T10:53:43.087 回答