问题描述
我正在开发一个Java应用程序,该应用程序包括Saxon软件包,以使用XSLT匹配XML中的文本字符串并返回ISBN号。
下面是库XML的示例:
<Library>
<Book>
<Title>Easy Book</Title>
<ISBN>978-3-16-148410-0</ISBN>
</Book>
<Book>
<Title>Tiger's Naptime Book</Title>
<ISBN>978-3-16-148410-1</ISBN>
</Book>
<Book>
<Title>How to "Capture" a CLever Tiger's Toe</Title>
<ISBN>978-3-16-148410-2</ISBN>
</Book>
</Library>
使用XSLT可以轻松找到第一本“简易书”:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="urn:developJava.com/NotWorking">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="Book/Title[text()='Easy Book']">
<xsl:value-of select='../ISBN' separator= ","/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
但是,我找不到标题:
<Title>Tiger's Naptime Book</Title>
使用此XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="urn:developJava.com/NotWorking">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="Book/Title[text()='Tiger's Naptime Book']">
<xsl:value-of select='../ISBN' separator= ","/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
或找到:
<Title>How to "Capture" a CLever Tiger's Toe</Title>
使用此XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ns1="urn:developJava.com/NotWorking">
<xsl:output omit-xml-declaration="yes"/>
<xsl:template match="Book/Title[text()='How to "Capture" a CLever Tiger's Toe']">
<xsl:value-of select='../ISBN' separator= ","/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
它正在处理标题中的"
和'
的嵌入式文本定界符。您对如何处理此XML / XSLT的想法将不胜感激。
谢谢!
解决方法
您可能会发现这很有用:
Using an xpath to find text with an apostrophe ( " ' ")
一般规则是:
-
要转义用作XPath字符串定界符的引号,请将它们加倍:
"
-
要转义用作XML属性定界符的引号,请将其写为
'
或match="Book/Title[text()='How to "Capture" a Clever Tiger''s Toe']"
:"
要了解其工作原理,请记住XML解析是在XPath解析之前进行的,因此像<xsl:variable name="q">How to "Capture" a Clever Tiger's Toe</xsl:variable>
<xsl:template match="*[contains(.,$q)]"/>
这样的XML实体的扩展需要传递一个有效的XPath表达式的属性值。
此外,还有另一种解决方案可能更具可读性:
{{1}},
谢谢迈克尔!
这是我的问题的正确答案,字面上是写这本书的绅士!我只添加一个简短的代码示例:
public static void main(String[] args) {
String inXML = "<Library>\r\n" +
" <Book>\r\n" +
" <Title>Easy Book</Title>\r\n" +
" <ISBN>978-3-16-148410-1</ISBN>\r\n" +
" </Book>\r\n" +
" <Book>\r\n" +
" <Title>Tiger's Naptime Book</Title>\r\n" +
" <ISBN>978-3-16-148410-1</ISBN>\r\n" +
" </Book>\r\n" +
" <Book>\r\n" +
" <Title>How to "Capture" a Clever Tiger's Toe</Title>\r\n" +
" <ISBN>978-3-16-148410-2</ISBN>\r\n" +
" </Book>\r\n" +
" </Library>";
// BUILD THE CUSTOM XSLT FOR THE modelPath
String stylesheet1 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
"<xsl:stylesheet version=\"2.0\"\r\n" +
"xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\r\n" +
" xmlns:ns1=\"urn:developJava.com/Working\">\r\n" +
"<xsl:output omit-xml-declaration=\"yes\"/>\n" + "<xsl:template match=\"Book/Title[text()='Tiger''s Naptime Book']\">\n" +
"<xsl:value-of select='../ISBN' separator= \",\"/>\r\n" +
"</xsl:template>\r\n" +
"<xsl:template match=\"text()\"/>\r\n" +
"</xsl:stylesheet>\r\n";
// BUILD THE CUSTOM XSLT FOR THE modelPath
String stylesheet2 = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n" +
"<xsl:stylesheet version=\"2.0\"\r\n" +
"xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"\r\n" +
" xmlns:ns1=\"urn:developJava.com/Working\">\r\n" +
"<xsl:output omit-xml-declaration=\"yes\"/>\n" + "<xsl:template match=\"Book/Title[text()='How to "Capture" a Clever Tiger''s Toe']\">\r\n" +
"<xsl:value-of select='../ISBN' separator= \",\"/>\r\n" +
"</xsl:template>\r\n" +
"<xsl:template match=\"text()\"/>\r\n" +
"</xsl:stylesheet>\r\n";
String result1 = "";
try {
result1 = XsltMethods.transformUsingXslt(stylesheet1,inXML);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("result 1:---" + result1 + "---");
String result2 = "";
try {
result2 = XsltMethods.transformUsingXslt(stylesheet2,inXML);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("result 2:---" + result2 + "---");
}
private static String transformUsingXslt(String stylesheet,String inXml)
throws IOException {
// CONVERT Strings TO AN INPUT FORM ACCEPTABLE TO XSLT TRANSFORMER
Source xsltSource = new StreamSource(new StringReader(stylesheet));
Source xmlSource = new StreamSource(new StringReader(inXml));
StringWriter writer = null;
String result = null;
try {
writer = new StringWriter();
TransformerFactory tFactory = TransformerFactory.newInstance("net.sf.saxon.TransformerFactoryImpl",null);
// TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(xsltSource);
transformer.transform(xmlSource,new javax.xml.transform.stream.StreamResult(writer));
result = writer.toString();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
return result;
}
执行代码将返回以下结果:
结果1:--- 978-3-16-148410-1 ---
结果2:--- 978-3-16-148410-2 ---