Skip to content

Commit

Permalink
Improvements to XInclude processing
Browse files Browse the repository at this point in the history
- Skip intermediate XInclude files when serializing multi-level document hierarchies.
- Rename XmlReadOptions::parentFilenames to XmlReadOptions::parentXIncludes for clarity.
- Remove a duplicate call to setSourceUri.
  • Loading branch information
jstone-lucasfilm committed Apr 2, 2019
1 parent 2b63e5d commit 59e73dd
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 9 deletions.
19 changes: 15 additions & 4 deletions source/MaterialXFormat/XmlIo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,19 @@ void processXIncludes(DocumentPtr doc, xml_node& xmlNode, const string& searchPa
string filename = xmlChild.attribute("href").value();

// Check for XInclude cycles.
if (readOptions && readOptions->parentFilenames.count(filename))
if (readOptions)
{
throw ExceptionParseError("XInclude cycle detected.");
const StringVec& parents = readOptions->parentXIncludes;
if (std::find(parents.begin(), parents.end(), filename) != parents.end())
{
throw ExceptionParseError("XInclude cycle detected.");
}
}

// Read the included file into a library document.
DocumentPtr library = createDocument();
XmlReadOptions xiReadOptions = readOptions ? *readOptions : XmlReadOptions();
xiReadOptions.parentFilenames.insert(filename);
xiReadOptions.parentXIncludes.push_back(filename);
readXIncludeFunction(library, filename, searchPath, &xiReadOptions);

// Import the library document.
Expand Down Expand Up @@ -256,7 +260,14 @@ void readFromXmlFile(DocumentPtr doc, const string& filename, const string& sear
xmlDocumentFromFile(xmlDoc, filename, searchPath);

documentFromXml(doc, xmlDoc, searchPath, readOptions);
doc->setSourceUri(filename);
if (readOptions && !readOptions->parentXIncludes.empty())
{
doc->setSourceUri(readOptions->parentXIncludes[0]);
}
else
{
doc->setSourceUri(filename);
}
}

void readFromXmlString(DocumentPtr doc, const string& str, const XmlReadOptions* readOptions)
Expand Down
6 changes: 3 additions & 3 deletions source/MaterialXFormat/XmlIo.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ class XmlReadOptions : public CopyOptions
/// needs to be read into a document. Defaults to readFromXmlFile.
XmlReadFunction readXIncludeFunction;

/// The set of parent filenames at the scope of the current document.
/// Defaults to an empty set.
StringSet parentFilenames;
/// The vector of parent XIncludes at the scope of the current document.
/// Defaults to an empty vector.
StringVec parentXIncludes;
};

/// @class XmlWriteOptions
Expand Down
1 change: 0 additions & 1 deletion source/MaterialXTest/GenShaderUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ void loadLibrary(const mx::FilePath& file, mx::DocumentPtr doc)
{
mx::DocumentPtr libDoc = mx::createDocument();
mx::readFromXmlFile(libDoc, file);
libDoc->setSourceUri(file);
mx::CopyOptions copyOptions;
copyOptions.skipDuplicateElements = true;
doc->importLibrary(libDoc, &copyOptions);
Expand Down
2 changes: 1 addition & 1 deletion source/PyMaterialX/PyMaterialXFormat/PyXmlIo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ void bindPyXmlIo(py::module& mod)
py::class_<mx::XmlReadOptions, mx::CopyOptions>(mod, "XmlReadOptions")
.def(py::init())
.def_readwrite("readXIncludeFunction", &mx::XmlReadOptions::readXIncludeFunction)
.def_readwrite("parentFilenames", &mx::XmlReadOptions::parentFilenames);
.def_readwrite("parentXIncludes", &mx::XmlReadOptions::parentXIncludes);

py::class_<mx::XmlWriteOptions>(mod, "XmlWriteOptions")
.def(py::init())
Expand Down

0 comments on commit 59e73dd

Please sign in to comment.