使用 XSLT 精确匹配 XML 包含 " 或 ' 的文本
Use XSLT to exactly match XML text containing " or '
我正在开发一个 Java 应用程序,其中包括使用 XSLT 匹配 XML 和 return ISBN 编号中的文本字符串的 Saxon 包。
下面是库的示例 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>
第一本“Easy Book”很容易找到,带有 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 字符串定界符的引号,将它们加倍:'Tiger''s Naptime Book'
转义用作 XML 属性定界符的引号,将它们写成 "
或 '
:match="Book/Title[text()='How to "Capture" a Clever Tiger''s Toe']"
要了解它的工作原理,请记住 XML 解析发生在 XPath 解析之前,因此 XML 实体的扩展如 "
需要提供一个有效的 XPath 属性值表达式。
此外,还有另一种解决方案可能更具可读性:
<xsl:variable name="q">How to "Capture" a Clever Tiger's Toe</xsl:variable>
<xsl:template match="*[contains(., $q)]"/>
谢谢迈克尔!
这是对我的问题的正确回答,来自写这本书的先生!我将添加一个简短的代码示例:
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;
}
执行代码returns结果如下:
结果 1:---978-3-16-148410-1---
结果 2:---978-3-16-148410-2---
我正在开发一个 Java 应用程序,其中包括使用 XSLT 匹配 XML 和 return ISBN 编号中的文本字符串的 Saxon 包。
下面是库的示例 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>
第一本“Easy Book”很容易找到,带有 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 字符串定界符的引号,将它们加倍:
'Tiger''s Naptime Book'
转义用作 XML 属性定界符的引号,将它们写成
"
或'
:match="Book/Title[text()='How to "Capture" a Clever Tiger''s Toe']"
要了解它的工作原理,请记住 XML 解析发生在 XPath 解析之前,因此 XML 实体的扩展如 "
需要提供一个有效的 XPath 属性值表达式。
此外,还有另一种解决方案可能更具可读性:
<xsl:variable name="q">How to "Capture" a Clever Tiger's Toe</xsl:variable>
<xsl:template match="*[contains(., $q)]"/>
谢谢迈克尔!
这是对我的问题的正确回答,来自写这本书的先生!我将添加一个简短的代码示例:
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;
}
执行代码returns结果如下:
结果 1:---978-3-16-148410-1---
结果 2:---978-3-16-148410-2---