SOLR-1040 -- XPathEntityProcessor fails with an xpath like containing forward slash in a attribute selector's value

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/trunk@748117 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Shalin Shekhar Mangar 2009-02-26 12:41:08 +00:00
parent c1e663e905
commit 59cbcf51a7
3 changed files with 41 additions and 1 deletions

View File

@ -155,6 +155,9 @@ Bug Fixes
19.SOLR-1037: DIH should not add null values in a row returned by EntityProcessor to documents.
(shalin)
20.SOLR-1040: XPathEntityProcessor fails with an xpath like /feed/entry/link[@type='text/html']/@href
(Noble Paul via shalin)
Documentation
----------------------

View File

@ -67,7 +67,7 @@ public class XPathRecordReader {
private void addField0(String xpath, String name, boolean multiValued,
boolean isRecord, int flags) {
List<String> paths = new LinkedList<String>(Arrays.asList(xpath.split("/")));
List<String> paths = splitEscapeQuote(xpath);
if ("".equals(paths.get(0).trim()))
paths.remove(0);
rootNode.build(paths, name, multiValued, isRecord, flags);
@ -367,6 +367,30 @@ public class XPathRecordReader {
return result;
}
/**
* Used for handling cases where there is a slash '/' character
* inside the attribute value e.g. x@html='text/html'. We need to split
* by '/' excluding the '/' which is a part of the attribute's value.
*/
private static List<String> splitEscapeQuote(String str) {
List<String> result = new LinkedList<String>();
String[] ss = str.split("/");
for (int i = 0; i < ss.length; i++) {
if (ss[i].length() == 0 && result.size() == 0) continue;
StringBuilder sb = new StringBuilder();
int quoteCount = 0;
while (true) {
sb.append(ss[i]);
for (int j = 0; j < ss[i].length(); j++) if (ss[i].charAt(j) == '\'') quoteCount++;
if ((quoteCount % 2) == 0) break;
i++;
sb.append("/");
}
result.add(sb.toString());
}
return result;
}
static XMLInputFactory factory = XMLInputFactory.newInstance();
static{
factory.setProperty(XMLInputFactory.IS_VALIDATING , Boolean.FALSE);

View File

@ -226,6 +226,19 @@ public class TestXPathRecordReader {
Assert.assertEquals(0, l.get(1).size());
}
@Test
public void attribValWithSlash() {
String xml = "<root><b>\n" +
" <a x=\"a/b\" h=\"hello-A\"/> \n" +
"</b></root>";
XPathRecordReader rr = new XPathRecordReader("/root/b");
rr.addField("x", "/root/b/a[@x='a/b']/@h", false);
List<Map<String, Object>> l = rr.getAllRecords(new StringReader(xml));
Assert.assertEquals(1, l.size());
Map<String, Object> m = l.get(0);
Assert.assertEquals("hello-A", m.get("x"));
}
@Test
public void another() {
String xml = "<root>\n"