@@ -101,6 +101,48 @@ bool validate_urdf_with_xsd_tag(const std::string & urdf)
101101 {
102102 return false ;
103103 }
104+ std::string xsd_package_share_dir =
105+ ament_index_cpp::get_package_share_directory (" hardware_interface" );
106+ // If the extracted XSD is a file URI (e.g. "file:///path/to/schema.xsd"), normalize to a local
107+ // path
108+ if (ros2_control_xsd.find (" file" ) != std::string::npos)
109+ {
110+ ros2_control_xsd.replace (0 , 8 , xsd_package_share_dir);
111+ }
112+ else if (ros2_control_xsd.find (" http" ) != std::string::npos)
113+ {
114+ {
115+ // Download the remote XSD to a local temporary file and point to it
116+ std::string filename;
117+ auto pos = ros2_control_xsd.find_last_of (' /' );
118+ if (pos == std::string::npos || pos + 1 >= ros2_control_xsd.size ())
119+ {
120+ filename = " ros2_control_schema.xsd" ;
121+ }
122+ else
123+ {
124+ filename = ros2_control_xsd.substr (pos + 1 );
125+ }
126+ std::string tmp_path = std::string (" /tmp/" ) + filename;
127+
128+ // Use curl to fetch the XSD; require curl to be available on PATH.
129+ std::ostringstream cmd;
130+ cmd << " curl -sSfL -o '" << tmp_path << " ' '" << ros2_control_xsd << " '" ;
131+
132+ int rc = std::system (cmd.str ().c_str ());
133+ if (rc != 0 )
134+ {
135+ // failed to download
136+ return false ;
137+ }
138+
139+ ros2_control_xsd = tmp_path;
140+ }
141+ }
142+ else
143+ {
144+ return false ;
145+ }
104146 return validate_urdf_with_xsd (urdf, ros2_control_xsd);
105147}
106148
@@ -114,10 +156,11 @@ bool extract_ros2_control_xsd_tag(const std::string & urdf, std::string & ros2_c
114156 xmlDocPtr doc = xmlReadMemory (urdf.c_str (), static_cast <int >(urdf.size ()), nullptr , nullptr , 0 );
115157 if (!doc)
116158 {
117- return {} ;
159+ return false ;
118160 }
119161
120162 xmlNodePtr root = xmlDocGetRootElement (doc);
163+ bool found = false ;
121164 if (root)
122165 {
123166 auto check = [&](xmlNsPtr ns) -> bool
@@ -131,20 +174,25 @@ bool extract_ros2_control_xsd_tag(const std::string & urdf, std::string & ros2_c
131174 }
132175 return false ;
133176 };
134- if (!check (root->ns ))
177+ if (check (root->ns ))
178+ {
179+ found = true ;
180+ }
181+ else
135182 {
136183 for (xmlNsPtr cur = root->nsDef ; cur; cur = cur->next )
137184 {
138185 if (check (cur))
139186 {
187+ found = true ;
140188 break ;
141189 }
142190 }
143191 }
144192 }
145193
146194 xmlFreeDoc (doc);
147- return false ;
195+ return found ;
148196}
149197
150198} // namespace hardware_interface
0 commit comments