Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 48 additions & 13 deletions src/org/rascalmpl/library/lang/xml/IO.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ public class IO {
private final IRascalValueFactory vf;
private static final String SRC_ATTR = "src";
private static final String QUALIFIED_SRC_ATTR = "rascal-src";
private static final String SRCS_ATTR = "srcs";
private static final String QUALIFIED_SRCS_ATTR = "rascal-srcs";

private static final TypeFactory tf = TypeFactory.getInstance();
// `Maybe[value] ()`
private static final Type nextFunctionType = tf.functionType(UtilMaybe.Maybe.instantiate(Map.of(UtilMaybe.ParameterT, tf.valueType())), tf.tupleEmpty(), tf.tupleEmpty());
Expand All @@ -76,7 +79,7 @@ public IValue readXML(ISourceLocation loc, IBool fullyQualify, IBool trackOrigin

try (InputStream reader = URIResolverRegistry.getInstance().getInputStream(loc)) {
Parser xmlParser = Parser.xmlParser()
.settings(new ParseSettings(false, false))
.settings(new ParseSettings(true, true))
.setTrackPosition(trackOrigins.getValue())
;

Expand Down Expand Up @@ -203,9 +206,17 @@ else if (a.getKey().equals("xmlns")) {
// remove all the namespace attributes
return !a.getKey().startsWith("xmlns");
})
.map(a -> removeNamespace(a, elem.attributes(), fullyQualify))
.collect(Collectors.toMap(a -> normalizeAttr(a.getKey()), a -> vf.string(a.getValue())));
.collect(Collectors.toMap(a -> normalizeAttr(a.getKey()), a -> vf.string(removeNamespace(a, elem.attributes(), fullyQualify))));

// we traverse again to record the source positions of each attribute
IMap Srcs = file != null ? StreamSupport.stream(elem.attributes().spliterator(), false)
.filter(a -> !a.getKey().startsWith("xmlns"))
.map(a -> vf.tuple(vf.string(normalizeAttr(removeNamespace(a, elem.attributes(), fullyQualify))), attrToLoc(a, file))) // key-value tuples for the map collector
.filter(t -> !t.get(1).equals(vf.tuple())) // remove the failed location lookups for robustness sake
.collect(vf.mapWriter())
: vf.map()
;

if (fullyQualify) {
IMap m = namespaces.done();

Expand All @@ -223,6 +234,9 @@ else if (a.getKey().equals("xmlns")) {

if (file != null) {
kws.put(kws.containsKey(SRC_ATTR) ? QUALIFIED_SRC_ATTR : SRC_ATTR, nodeToLoc((Element) node, file, includeEndTags));
if (!Srcs.isEmpty()) {
kws.put(kws.containsKey(SRCS_ATTR) ? QUALIFIED_SRCS_ATTR : SRCS_ATTR, Srcs);
}
}

return vf.node(removeNamespace(node.nodeName(), fullyQualify), args).asWithKeywordParameters().setParameters(kws);
Expand All @@ -246,26 +260,47 @@ private static String removeNamespace(String name, boolean fullyQualify) {
return name.substring(index+1);

}
private static Attribute removeNamespace(Attribute a, Attributes otherAttributes, boolean fullyQualify) {
private static String removeNamespace(Attribute a, Attributes otherAttributes, boolean fullyQualify) {
if (fullyQualify) {
return a;
return a.getKey();
}

String key = a.getKey();
int index = key.indexOf(":");

if (index == -1) {
return a;
return a.getKey();
}

String newKey = key.substring(index+1);

if (otherAttributes.hasKey(newKey)) {
// keep disambiguation if necessary
return a;
}
return key.substring(index+1);
}

return new Attribute(newKey, a.getValue());
private ITuple attrToLoc(Attribute a, ISourceLocation file) {
Range nameRange = a.sourceRange().nameRange();
Range valueRange = a.sourceRange().valueRange();

if (valueRange.start().pos() < 0 || nameRange.start().pos() < 0) {
// this is strange, tagging an error here so it can be filtered.
assert false;
return vf.tuple();
}

return vf.tuple(
vf.sourceLocation(file,
nameRange.start().pos(),
nameRange.end().pos() - nameRange.start().pos(),
nameRange.start().lineNumber(),
nameRange.end().lineNumber(),
nameRange.start().columnNumber() - 1,
nameRange.end().columnNumber() - 1)
, vf.sourceLocation(file,
valueRange.start().pos(),
valueRange.end().pos() - valueRange.start().pos(),
valueRange.start().lineNumber(),
valueRange.end().lineNumber(),
valueRange.start().columnNumber() - 1,
valueRange.end().columnNumber() - 1)
);
}

private ISourceLocation nodeToLoc(Element node, ISourceLocation file, boolean includeEndTags) {
Expand Down
Loading