1


我目前正在开发一个使用 XSL 转换从 XML 生成 HTML 的项目。在输入字段上,我必须设置一些属性。
样本:

<input name="/my/xpath/to/node"
       class="{/my/xpath/to/node/@isValid}"
       value="{/my/xpath/to/node}" />

这很愚蠢,因为我必须编写相同的 XPath 3 次......我的想法是为 xsl 文件配备某种后处理器,这样我就可以编写:

<input xpath="/my/xpath/to/node" />

我正在使用类似的东西来转换我的xml

import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;

import org.dom4j.Document;
import org.dom4j.io.DocumentResult;
import org.dom4j.io.DocumentSource;

public class Foo {

    public Document styleDocument(
        Document document, 
        String stylesheet
    ) throws Exception {

        // load the transformer using JAXP
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer = factory.newTransformer( 
            new StreamSource( stylesheet ) 
        );

        // now lets style the given document
        DocumentSource source = new DocumentSource( document );
        DocumentResult result = new DocumentResult();
        transformer.transform( source, result );

        // return the transformed document
        Document transformedDoc = result.getDocument();
        return transformedDoc;
    }
}

我希望我可以从 Document 对象中创建一个 Transformer 对象。但它似乎必须是文件路径 - 至少我找不到直接使用 Document 的方法。
任何人都知道实现我想要的方法吗?

谢谢

4

2 回答 2

2

为什么不跳过后处理,并在 XSLT 中使用它:

<xsl:variable name="myNode" select="/my/xpath/to/node" />

<input name="/my/xpath/to/node"
   class="{$myNode/@isValid}"
   value="{$myNode}" />

这让你更接近。

如果您真的想 DRY(显然您是这样做的),您甚至可以使用一个变量myNodePath,通过模板或用户定义的函数从 $myNode 生成值。名称是否真的必须是 XPath 表达式(而不是generate-id()?)

更新:

示例代码:

<xsl:variable name="myNode" select="/my/xpath/to/node" />
<xsl:variable name="myNodeName">
  <xsl:apply-template mode="generate-xpath" select="$myNode" />
</xsl:variable>

<input name="{$myNodeName}"
   class="{$myNode/@isValid}"
   value="{$myNode}" />

模式的模板generate-xpath可在网络上获得...例如,您可以使用Schematron附带的模板之一。转到此页面,下载 iso-schematron-xslt1.zip,然后查看 iso_schematron_skeleton_for_xslt1.xsl。(如果您能够使用 XSLT 2.0,请下载该 zip 存档。)

在那里,您会发现 的几个实现schematron-select-full-path,您可以将它们用于generate-xpath. 一个版本是精确的,最适合程序使用;另一个更具人类可读性。请记住,对于 XML 文档中的任何给定节点,有大量 XPath 表达式可用于仅选择该节点。因此,您可能不会得到与开始时相同的 XPath 表达式。如果这是一个交易破坏者,您可能想尝试另一种方法,例如...

使用另一个 XSLT 样式表(称为 B)生成您的 XSLT 样式表(您已经在开发的样式表,称为 A)。当 B 生成 A 时,B 有机会将 XPath 表达式输出为带引号的字符串和将被评估的表达式。这基本上是 XSLT 中的预处理,而不是 Java 中的后处理。我不确定它是否适用于您的情况。如果我知道输入 XML 的样子,我认为会更容易弄清楚。

于 2011-11-13T12:37:43.957 回答
0

我希望我可以从 Document 对象中创建一个 Transformer 对象。但它似乎必须是文件路径 - 至少我找不到直接使用 Document 的方法。

您可以从文档对象创建 Transformer 对象:

    Document stylesheetDoc = loadStylesheetDoc(stylesheet);
    // load the transformer using JAXP
    TransformerFactory factory = TransformerFactory.newInstance();
    Transformer transformer = factory.newTransformer( 
        new DOMSource( stylesheetDoc ) 
    );

实施loadStylesheetDoc留作练习。您可以在内部构建样式表Document或使用 jaxp 加载它,您甚至可以将所需的更改写入它,作为另一个转换样式表的 XSLT 转换。

于 2011-11-13T13:15:11.993 回答