这个 SAX 解析和 Xpath 代码有什么问题?
what is wrong with this SAX parsing and Xpath code?
通读 Maven By Example,这是几年前的一本书,但我假设是从存储库中检索正确的版本,我只是想知道第一个单元测试出了什么问题例如。
我们有一个 xml 文件,文件开头:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<channel>
<title>Yahoo! Weather - New York, NY</title>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/New_York__NY/*http://weather.yahoo.com/forecast/10002_f.html</link>
<description>Yahoo! Weather for New York, NY</description>
<language>en-us</language>
<lastBuildDate>Sat, 10 Nov 2007 8:51 pm EDT</lastBuildDate>
<ttl>60</ttl>
<!--************ THIS IS THE LINE WE'RE INTERESTED IN ************ -->
<yweather:location city="New York" region="NY" country="US" />
<yweather:units temperature="F" distance="mi" pressure="in" speed="mph" />
并且这个 xml 文件正在通过 InputStream 读入并解析:
Weather weather = new Weather();
log.info("Creating XML Reader");
SAXReader xmlReader = createXmlReader();
Document doc = xmlReader.read(inputStream);
// this proves we're getting the text OK
// String xml_text_content = doc.getStringValue();
// log.info( "=== xml text content: |" + xml_text_content + "|" );
log.info("Parsing XML Response");
weather.setCity(doc.valueOf("/rss/channel/y:location/@city"));
String city_str = doc.valueOf("/rss/channel/y:location/@city");
// this should say "New York"... but I'm getting an empty string
log.info( "=== doc value of for city: |" + city_str + "|" );
...我对RSS和XPath知之甚少,抱歉。好像有知识的人可能会看到问题!
PS 我尝试在 xml 文件中将 "yweather:location" 更改为 "y:location",然后在代码中将 "y:location" 更改为 "yweather:location"。 .. 都抛出异常。后一种情况:
528 INFO YahooParser - Parsing XML Response Tests run: 1, Failures:
0, Errors: 1, Skipped: 0, Time elapsed: 0.096 sec <<< FAILURE!
testParser(org.sonatype.mavenbook.custom.weather.yahoo.YahooParserTest)
Time el apsed: 0.094 sec <<< ERROR!
org.dom4j.XPathException:
Exception occurred evaluting XPath: /rss/channel/yweather:location/@city. Exception: XPath expression uses unbound namespace
prefix yweather
at org.dom4j.xpath.DefaultXPath.handleJaxenException(DefaultXPath.java:374)
at org.dom4j.xpath.DefaultXPath.valueOf(DefaultXPath.java:185)
at org.dom4j.tree.AbstractNode.valueOf(AbstractNode.java:191)
at org.sonatype.mavenbook.custom.weather.YahooParser.parse(YahooParser.j
ava:28)
at org.sonatype.mavenbook.custom.weather.yahoo.YahooParserTest.testParse
r(YahooParserTest.java:36)
"unbound namespace prefix yweather"...???
以下代码适用于我:
import java.io.File;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
public class TestSax {
public static void main(String[] args) throws DocumentException {
SAXReader xmlReader = new SAXReader();
Document doc = xmlReader.read(new File("D:/Temp/sax.xml"));
String city_str = doc.valueOf("/rss/channel/yweather:location/@city");
System.out.println( "=== doc value of for city: |" + city_str + "|" );
}
}
我使用了 dom4j 并需要来自 here 的 jar jaxen。检查您是否使用相同的库。
另请注意,我将代码 y:location
更改为 yweather:location
。
只需提供解决方案(对我有用),以防同一本书的任何读者遇到同样的问题。
在第 38 页(在我的版本中)- 第 4.3 节 "Creating the Simple Weather Project",我们被告知 运行 这个命令:
$ mvn archetype:generate -DgroupId=org.sonatype.mavenbook.custom
DartifactId=simple-weather -Dversion=1.0
在我的系统上 (Windows 7) 这创建了错误的目录结构:在 "main" 和 "test" 下有一个 "spurious" 目录在 "mavenbook": "custom".
在第 43 页,当您开始创建 "main" 和 "test" 目录结构时,比我聪明的人会明白 "custom" 目录不应该存在...
我的解决方案(我终于找到了)确实是摆脱这个 "custom" 目录,确保路径在 xxxxTest 类 的导入语句中匹配 OK,最后到确保父 pom.xml 与目录 "simple-weather" 在同一目录中(项目 pom.xml 在后一个目录中)。
也可以按照书中的解释下载现成的项目(因为它本来就是,没有 "custom" 目录)...
PS 我觉得这是值得的 - 如果您的 builder/tester 应用程序没有按预期工作,您将何去何从?
PPS 这也是值得的,因为 Maven 确实设计得很好而且功能强大...
回复旧 post 以防有人想知道解决方案(比如我)我同意上面的自定义文件夹问题,但它缺少 XPath 问题的实际解决方案。
本书有
private SAXReader createXmlReader() {
Map<String,String> uris = new HashMap<String,String>();
uris.put( "y", "http://xml.weather.yahoo.com/ns/rss/1.0" );
将散列键更改为 'yweather',将 Xpath 更改为 yweather:location(在代码中,只要 y: 应该是 yweather:....),如上面的评论将起作用
uris.put( "yweather", "http://xml.weather.yahoo.com/ns/rss/1.0" );
通读 Maven By Example,这是几年前的一本书,但我假设是从存储库中检索正确的版本,我只是想知道第一个单元测试出了什么问题例如。
我们有一个 xml 文件,文件开头:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<rss version="2.0" xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#">
<channel>
<title>Yahoo! Weather - New York, NY</title>
<link>http://us.rd.yahoo.com/dailynews/rss/weather/New_York__NY/*http://weather.yahoo.com/forecast/10002_f.html</link>
<description>Yahoo! Weather for New York, NY</description>
<language>en-us</language>
<lastBuildDate>Sat, 10 Nov 2007 8:51 pm EDT</lastBuildDate>
<ttl>60</ttl>
<!--************ THIS IS THE LINE WE'RE INTERESTED IN ************ -->
<yweather:location city="New York" region="NY" country="US" />
<yweather:units temperature="F" distance="mi" pressure="in" speed="mph" />
并且这个 xml 文件正在通过 InputStream 读入并解析:
Weather weather = new Weather();
log.info("Creating XML Reader");
SAXReader xmlReader = createXmlReader();
Document doc = xmlReader.read(inputStream);
// this proves we're getting the text OK
// String xml_text_content = doc.getStringValue();
// log.info( "=== xml text content: |" + xml_text_content + "|" );
log.info("Parsing XML Response");
weather.setCity(doc.valueOf("/rss/channel/y:location/@city"));
String city_str = doc.valueOf("/rss/channel/y:location/@city");
// this should say "New York"... but I'm getting an empty string
log.info( "=== doc value of for city: |" + city_str + "|" );
...我对RSS和XPath知之甚少,抱歉。好像有知识的人可能会看到问题!
PS 我尝试在 xml 文件中将 "yweather:location" 更改为 "y:location",然后在代码中将 "y:location" 更改为 "yweather:location"。 .. 都抛出异常。后一种情况:
528 INFO YahooParser - Parsing XML Response Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.096 sec <<< FAILURE! testParser(org.sonatype.mavenbook.custom.weather.yahoo.YahooParserTest) Time el apsed: 0.094 sec <<< ERROR!
org.dom4j.XPathException: Exception occurred evaluting XPath: /rss/channel/yweather:location/@city. Exception: XPath expression uses unbound namespace prefix yweather
at org.dom4j.xpath.DefaultXPath.handleJaxenException(DefaultXPath.java:374) at org.dom4j.xpath.DefaultXPath.valueOf(DefaultXPath.java:185) at org.dom4j.tree.AbstractNode.valueOf(AbstractNode.java:191) at org.sonatype.mavenbook.custom.weather.YahooParser.parse(YahooParser.j ava:28) at org.sonatype.mavenbook.custom.weather.yahoo.YahooParserTest.testParse r(YahooParserTest.java:36)
"unbound namespace prefix yweather"...???
以下代码适用于我:
import java.io.File;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.io.SAXReader;
public class TestSax {
public static void main(String[] args) throws DocumentException {
SAXReader xmlReader = new SAXReader();
Document doc = xmlReader.read(new File("D:/Temp/sax.xml"));
String city_str = doc.valueOf("/rss/channel/yweather:location/@city");
System.out.println( "=== doc value of for city: |" + city_str + "|" );
}
}
我使用了 dom4j 并需要来自 here 的 jar jaxen。检查您是否使用相同的库。
另请注意,我将代码 y:location
更改为 yweather:location
。
只需提供解决方案(对我有用),以防同一本书的任何读者遇到同样的问题。
在第 38 页(在我的版本中)- 第 4.3 节 "Creating the Simple Weather Project",我们被告知 运行 这个命令:
$ mvn archetype:generate -DgroupId=org.sonatype.mavenbook.custom DartifactId=simple-weather -Dversion=1.0
在我的系统上 (Windows 7) 这创建了错误的目录结构:在 "main" 和 "test" 下有一个 "spurious" 目录在 "mavenbook": "custom".
在第 43 页,当您开始创建 "main" 和 "test" 目录结构时,比我聪明的人会明白 "custom" 目录不应该存在...
我的解决方案(我终于找到了)确实是摆脱这个 "custom" 目录,确保路径在 xxxxTest 类 的导入语句中匹配 OK,最后到确保父 pom.xml 与目录 "simple-weather" 在同一目录中(项目 pom.xml 在后一个目录中)。
也可以按照书中的解释下载现成的项目(因为它本来就是,没有 "custom" 目录)...
PS 我觉得这是值得的 - 如果您的 builder/tester 应用程序没有按预期工作,您将何去何从?
PPS 这也是值得的,因为 Maven 确实设计得很好而且功能强大...
回复旧 post 以防有人想知道解决方案(比如我)我同意上面的自定义文件夹问题,但它缺少 XPath 问题的实际解决方案。
本书有
private SAXReader createXmlReader() {
Map<String,String> uris = new HashMap<String,String>();
uris.put( "y", "http://xml.weather.yahoo.com/ns/rss/1.0" );
将散列键更改为 'yweather',将 Xpath 更改为 yweather:location(在代码中,只要 y: 应该是 yweather:....),如上面的评论将起作用
uris.put( "yweather", "http://xml.weather.yahoo.com/ns/rss/1.0" );