我目前正在开发一个使用XSL-Transformations从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的方法。
谁知道实现我想要的方法?
感谢
答案 0 :(得分:2)
为什么不跳过后处理,并在XSLT中使用它:
<xsl:variable name="myNode" select="/my/xpath/to/node" />
<input name="/my/xpath/to/node"
class="{$myNode/@isValid}"
value="{$myNode}" />
让你更接近。
如果你真的想要干(显然你做),你甚至可以使用变量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附带的其中一个模板。转到this page,下载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是什么样的,那么我认为更容易理解。
答案 1 :(得分: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转换变换样式表所需的更改。